# @plyaz/core

> Foundational full-stack framework for the Plyaz ecosystem

The `@plyaz/core` package serves as the orchestration layer that provides domain service infrastructure, automatic dependency injection, and unified service management across frontend and backend environments.

## Key Features

- **Domain Service Framework** - Base classes for backend and frontend services with automatic CRUD, validation, and lifecycle hooks
- **Service Registry** - Centralized service management with automatic dependency injection
- **Unified Infrastructure** - Single initialization for DB, API, Cache, Storage, Notifications, and Observability
- **Multi-Runtime Support** - Node.js, Next.js, NestJS, Browser, Edge, Bun, Deno
- **Event-Driven Architecture** - Typed events with CoreEventManager
- **Feature Flags** - Rule-based evaluation with targeting and rollouts
- **CLI Tooling** - Interactive feature generation with `plyaz-core`

## Quick Start

### Backend Service

```typescript
import { Core, ServiceRegistry } from '@plyaz/core';

// Initialize all services at once
await Core.initialize({
  db: {
    adapter: 'sql',
    sql: { connectionString: process.env.DATABASE_URL },
  },
  api: {
    baseUrl: process.env.API_BASE_URL,
  },
  cache: {
    provider: 'memory',
    ttl: 300,
  },
});

// Register domain services
ServiceRegistry.register({
  key: 'users',
  serviceClass: UserDomainService,
  config: { enabled: true },
});

// Get service instance with injected dependencies
const userService = await ServiceRegistry.getAsync<UserDomainService>('users');
const user = await userService.getById('user-123');
```

### Creating Domain Services

```typescript
import { BaseBackendDomainService } from '@plyaz/core/backend';

class UserDomainService extends BaseBackendDomainService<
  UserConfig,
  UserRepository,
  User,
  CreateUserDTO,
  UpdateUserDTO
> {
  protected eventPrefix = 'user';

  // Fluent queries via repository.query()
  async findActiveAdmins() {
    return this.repository.query()
      .where('status', 'eq', 'active')
      .andWhere('role', 'eq', 'admin')
      .orderByDesc('createdAt')
      .getMany();
  }

  // Lifecycle hooks
  protected async afterCreate(entity: User) {
    await this.sendWelcomeEmail(entity);
  }
}
```

## Architecture

```
@plyaz/core
├── init/                    # Core initialization & ServiceRegistry
├── services/                # Infrastructure services
│   ├── DbService           # Database (wraps @plyaz/db)
│   ├── ApiClientService    # HTTP client (wraps @plyaz/api)
│   ├── CacheService        # Caching (memory/redis)
│   ├── StorageService      # File storage (Supabase/R2)
│   ├── NotificationService # Email/SMS/Push (Infobip/SendGrid)
│   └── ObservabilityService # Metrics, tracing, logging
├── domain/                  # Base domain service classes
│   ├── BaseDomainService
│   ├── BaseBackendDomainService
│   └── BaseFrontendDomainService
├── events/                  # CoreEventManager
├── models/                  # Repositories & data access
└── adapters/               # NestJS, Next.js integrations
```

## Service Injection Flow

```
Core.initialize(config)
    ↓
ServiceRegistry.initialize()
    ↓
Build service configs (db, api, cache, storage, notifications)
    ↓
ServiceRegistry.register({ key, serviceClass, config })
    ↓
DomainService.create(config, { injected: { db, api, cache, storage, notifications } })
    ↓
Access via this.config.injected?.db / storage / notifications
```

## Infrastructure Services

### DbService

Database connection manager with adapter chain (soft delete, caching, audit, encryption):

```typescript
import { DbService } from '@plyaz/core';

await DbService.initialize({
  adapter: 'sql',
  sql: { connectionString: process.env.DATABASE_URL },
  softDelete: { enabled: true },
  cache: { enabled: true, ttl: 300 },
});

const db = DbService.getInstance().getDatabase();
```

### CacheService (Backend-only)

Server-side caching with Redis or in-memory providers:

```typescript
import { CacheService } from '@plyaz/core';

await CacheService.initialize({
  strategy: 'redis',
  ttl: 300,
  redisConfig: {
    url: process.env.REDIS_URL,
    keyPrefix: 'app:',
  },
});

const cache = CacheService.getInstance();
await cache.set('user:123', userData, 600); // 10 minute TTL
const cached = await cache.get('user:123');
```

### StorageService (Backend-only)

Multi-provider file storage with automatic routing:

```typescript
import { StorageService } from '@plyaz/core';

const storage = StorageService.getInstance().getStorage();
await storage.uploadFile({
  file: buffer,
  filename: 'document.pdf',
  bucket: 'documents',
});
```

### NotificationService (Backend-only)

Multi-channel notifications with provider failover:

```typescript
import { NotificationService } from '@plyaz/core';

const notifications = NotificationService.getInstance().getNotifications();
await notifications.sendEmail({
  to: 'user@example.com',
  templateId: 'welcome',
  templateData: { name: 'John' },
});
```

## QueryBuilder Integration

Fluent query API via `@plyaz/db` integrated with BaseRepository:

```typescript
// In domain service
const users = await this.repository.query()
  .where('status', 'eq', 'active')
  .andWhere('tier', 'eq', 'premium')
  .whereNotNull('verifiedAt')
  .orderByDesc('createdAt')
  .paginate(1, 25)
  .getMany();

// Raw SQL for complex queries
const results = await this.repository.query()
  .where('status', 'eq', 'active')
  .whereRaw('"metadata"->\'score\' > $1', [80])
  .getMany();
```

## CLI

Generate features interactively:

```bash
# Interactive mode
pnpm plyaz-core generate

# Direct generation
pnpm plyaz-core generate user --type backend

# Options
--type backend|frontend|universal
--skip-validator
--skip-mapper
--dry-run
```

## Feature Flags

```typescript
import { useFeatureFlag } from '@plyaz/core/frontend';

// React hook
const isEnabled = useFeatureFlag('DARK_MODE');

// Backend check
const flags = await FeatureFlagService.getFlags();
if (flags.PREMIUM_FEATURES) {
  // Premium logic
}
```

## Documentation

| Guide | Description |
|-------|-------------|
| [Quick Start](./docs/guides/01-QUICK-START.md) | Get started in 5 minutes |
| [Architecture](./docs/guides/02-ARCHITECTURE.md) | System design overview |
| [Initialization](./docs/guides/03-INITIALIZATION.md) | Configuration options |
| [Services](./docs/guides/05-SERVICES.md) | Domain service patterns |
| [Base Classes API](./docs/guides/09-BASE-CLASSES-API.md) | Full API reference |
| [DbService Guide](./docs/DbService-Usage-Guide.md) | Database integration |
| [CacheService Guide](./docs/CacheService-Usage-Guide.md) | Caching (Redis/in-memory) |
| [StorageService Guide](./docs/StorageService-Usage-Guide.md) | File storage |
| [NotificationService Guide](./docs/NotificationService-Usage-Guide.md) | Notifications |

## Related Packages

| Package | Purpose |
|---------|---------|
| `@plyaz/db` | Database adapters, repositories, QueryBuilder |
| `@plyaz/api` | HTTP client, fetchers, request handling |
| `@plyaz/storage` | File storage providers (Supabase, R2) |
| `@plyaz/notifications` | Email/SMS/Push providers |
| `@plyaz/types` | Shared TypeScript types |
| `@plyaz/errors` | Error handling utilities |

## Development

```bash
# Install dependencies
pnpm install

# Development
pnpm dev           # Watch mode
pnpm build         # Build package
pnpm type:check    # Type checking

# Testing
pnpm test          # Run tests
pnpm test:watch    # Watch mode
pnpm test:coverage # With coverage

# Code quality
pnpm lint          # Lint code
pnpm lint:fix      # Fix issues
pnpm format        # Format code

# NestJS server (if configured)
pnpm nest:dev      # Development server
pnpm nest:start    # Production server
```

## License

MIT
