# SSO VietProDev Backend

Production-ready SSO Authorization Server built with TypeScript, Express.js, and Sequelize — supports **OIDC/OAuth2**, **bcryptjs**, **PostgreSQL**, **MongoDB audit logs**, and **Redis**.

## Quick Start

```bash
pnpm install
cp .env.example .env          # fill in DB, Redis, JWT, OIDC, MongoDB values
docker compose up -d          # start PostgreSQL, MongoDB, Redis, MinIO
pnpm migrate                  # run SQL migrations (001-036)
pnpm dev                      # start development server
```

**Server**: `http://localhost:3001`
**Swagger UI**: `http://localhost:3001/swagger/index`
**OIDC Discovery**: `http://localhost:3001/.well-known/openid-configuration`

---

## Architecture

```
Browser/App
    │
    ├─ REST API (JWT) ──── Express Backend
    │   └─ /api/v1/* (auto-routed controllers)
    │
    └─ OIDC Flow ────────── oidc-provider
        ├─ /.well-known/openid-configuration
        ├─ /oauth/authorize
        ├─ /oauth/token
        ├─ /oauth/userinfo
        ├─ /oauth/logout
        └─ /oidc/interaction/* (login, register, consent)

PostgreSQL ── users, roles, permissions, sessions, clients, oidc_grants
MongoDB ───── audit_logs
Redis ─────── rate limiting, caching, sessions
```

## Stack

| Layer | Technology |
|---|---|
| Runtime | Node.js 20 + TypeScript |
| Framework | Express.js + express-automatic-routes |
| ORM | Sequelize (PostgreSQL) |
| Auth | OIDC/OAuth2 (oidc-provider) + JWT |
| Password | bcryptjs |
| Audit | MongoDB |
| Cache | Redis |
| Docs | OpenAPI 3.0 (Zod + zod-to-openapi) |

---

## Important Notes

**Database Schema Changes**: NEVER modify database structure directly. Always use migration files in `sql/migrations/`.

```sql
REVOKE CREATE ON SCHEMA public FROM app_user;
REVOKE ALTER ON ALL TABLES IN SCHEMA public FROM app_user;
```

---

## Important Commands

### Development

| Command | Description |
|---|---|
| `pnpm dev` / `pnpm start:dev` | Run development server with hot reload |
| `pnpm build` | Build for production |
| `pnpm start` | Run production server |
| `pnpm docker:dev` | Run with Docker Compose (full stack) |

### Database

| Command | Description |
|---|---|
| `pnpm migrate` | Run SQL migrations |
| `pnpm seed` | Seed default data |
| `pnpm db:setup` | Run migrations + seeds |
| `pnpm gen-db` | Generate models from database |

### Quality

| Command | Description |
|---|---|
| `pnpm lint` | ESLint check |
| `pnpm type-check` | TypeScript check |
| `pnpm quality:check` | lint + type-check + swagger + coverage |
| `pnpm swagger:validate` | Generate then validate Swagger spec |

### Testing

| Command | Description |
|---|---|
| `pnpm test:unit` | Unit tests only |
| `pnpm test:integration` | Integration tests only |
| `pnpm test:coverage` | Full suite + coverage report |
| `pnpm test:critical` | Critical gate — auth + security |

---

## OIDC Endpoints

| Endpoint | Description |
|---|---|
| `GET /.well-known/openid-configuration` | OIDC Discovery document |
| `GET /oauth/authorize` | Authorization endpoint |
| `POST /oauth/token` | Token endpoint |
| `GET /oauth/userinfo` | UserInfo endpoint |
| `GET /oauth/jwks` | JWKS endpoint |
| `POST /oauth/revoke` | Token revocation |
| `POST /oauth/introspect` | Token introspection |
| `GET /oidc/interaction/:uid` | Login page |
| `POST /oidc/interaction/:uid/login` | Submit login |
| `POST /oidc/interaction/:uid/register` | Register account |
| `POST /oidc/interaction/:uid/confirm` | Approve consent |
| `POST /oidc/interaction/:uid/cancel` | Cancel consent |

---

## Docs

| Topic | Link |
|---|---|
| Setup & Environment | [docs/setup.md](docs/setup.md) |
| New API Development | [docs/api-development.md](docs/api-development.md) |
| Error Handling | [docs/error-handling.md](docs/error-handling.md) |
| Configuration | [docs/configuration.md](docs/configuration.md) |
| Swagger / OpenAPI | [docs/swagger.md](docs/swagger.md) |
| Architecture | [docs/architecture.md](docs/architecture.md) |
| Testing | [docs/testing.md](docs/testing.md) |
| Conventions | [docs/conventions.md](docs/conventions.md) |
| Security | [docs/security.md](docs/security.md) |
