azcodr 1.3.0 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/.agents/hooks.json.example +42 -0
  2. package/.agents/mcp_config.json.example +24 -0
  3. package/.agents/skills/agentic-architect/SKILL.md +14 -7
  4. package/.agents/skills/agentic-architect/references/agents_md_template.md +6 -3
  5. package/.agents/skills/agentic-architect/references/skill_architecture_inquiry.md +1 -1
  6. package/.agents/skills/agentic-architect/references/skill_template.md +2 -1
  7. package/.agents/skills/agentic-architect/scripts/validate_agentic_configs.sh +156 -4
  8. package/.agents/skills/clean-code-refactor/SKILL.md +6 -6
  9. package/.agents/skills/compliance-audit/SKILL.md +1 -1
  10. package/.agents/skills/lets-build/SKILL.md +12 -4
  11. package/.agents/skills/lets-build/references/hexagonal_bootstrap_scaffolds.md +1 -1
  12. package/.agents/skills/lets-build/references/project_readme_template.md +4 -4
  13. package/.agents/skills/lets-build/scripts/bootstrap_workspace.sh +63 -35
  14. package/.agents/skills/relentless-questioner/SKILL.md +10 -5
  15. package/AGENTS.md +25 -40
  16. package/README.md +27 -40
  17. package/bin/azcodr.js +1 -1
  18. package/docs/rules/agentic_configuration.md +120 -32
  19. package/docs/rules/api_architecture.md +179 -0
  20. package/docs/rules/caching.md +30 -13
  21. package/docs/rules/cloud_native.md +10 -12
  22. package/docs/rules/cqrs.md +203 -0
  23. package/docs/rules/database_design.md +125 -0
  24. package/docs/rules/database_operations.md +56 -14
  25. package/docs/rules/design_patterns.md +18 -11
  26. package/docs/rules/devops_ci_cd.md +76 -0
  27. package/docs/rules/domain_driven_design.md +17 -13
  28. package/docs/rules/feature_flags.md +21 -4
  29. package/docs/rules/frontend_architecture.md +157 -0
  30. package/docs/rules/multitenancy_architecture.md +98 -0
  31. package/docs/rules/product_ownership.md +22 -27
  32. package/docs/rules/requirements_engineering.md +16 -14
  33. package/docs/rules/security_compliance.md +53 -0
  34. package/docs/rules/server_driven_ui.md +20 -3
  35. package/docs/rules/test_driven_development.md +118 -62
  36. package/docs/rules/type_safety.md +65 -0
  37. package/docs/rules/ui_ux_architecture.md +33 -30
  38. package/docs/rules/workflow_state_machines.md +20 -3
  39. package/lib/scaffold.js +9 -0
  40. package/memory.md +149 -15
  41. package/package.json +2 -2
  42. package/docs/rules/accessibility.md +0 -31
  43. package/docs/rules/advanced_api_patterns.md +0 -104
  44. package/docs/rules/api_versioning.md +0 -113
  45. package/docs/rules/application_security.md +0 -23
  46. package/docs/rules/architecture_decision_records.md +0 -42
  47. package/docs/rules/compliance.md +0 -25
  48. package/docs/rules/container_infrastructure.md +0 -32
  49. package/docs/rules/continuous_deployment.md +0 -24
  50. package/docs/rules/continuous_integration.md +0 -20
  51. package/docs/rules/continuous_learning.md +0 -29
  52. package/docs/rules/database_integrity.md +0 -80
  53. package/docs/rules/database_migrations.md +0 -41
  54. package/docs/rules/database_performance.md +0 -44
  55. package/docs/rules/database_transactions.md +0 -81
  56. package/docs/rules/devsecops.md +0 -33
  57. package/docs/rules/multitenancy_isolation.md +0 -88
  58. package/docs/rules/react.md +0 -78
  59. package/docs/rules/rest_api_conventions.md +0 -46
  60. package/docs/rules/tenant_dynamic_schemas.md +0 -88
  61. package/docs/rules/tenant_pluggable_logic.md +0 -59
  62. package/docs/rules/test_isolation.md +0 -26
  63. package/docs/rules/typescript.md +0 -55
  64. package/docs/rules/ui_navigation.md +0 -20
  65. package/docs/rules/workspace_isolation.md +0 -25
@@ -1,27 +1,69 @@
1
- # Database Operations, PITR & Least-Privilege Roles
1
+ # Database Operations, Migrations & Performance Engineering
2
2
 
3
- > **Core Mandate:** Enforce continuous Point-In-Time Recovery (PITR), causal read-after-write routing, non-blocking table maintenance, connection pooling, and least-privilege role separation.
3
+ > **Core Mandate:** Enforce zero-downtime expand-contract migrations via declarative tools, systematic N+1 query elimination via DataLoader/batching, composite tenant indexing, connection pooling, and continuous point-in-time recovery (PITR).
4
4
 
5
5
  ---
6
6
 
7
- ## 1. High Availability, Backups & Disaster Recovery (DR)
7
+ ## 1. Zero-Downtime Expand-Contract Migrations
8
8
 
9
- - **Continuous Point-In-Time Recovery (PITR)**: Utilize continuous write-ahead logging (WAL) archiving and periodic base backups (**WAL-G**, **pgBackRest**, or engine-native tooling) to guarantee restoration to any specific second.
10
- - **Causal Read-After-Write Consistency**: Read replicas experience asynchronous replication lag. Immediately following a state-mutating command (`POST`, `PUT`, `DELETE`), pin client sessions to the primary database instance for a bounded window (e.g. 2 seconds) before resuming read-replica routing.
9
+ Database schema migrations must never require maintenance windows or downtime. Follow the **3-Phase Expand-Contract Pattern**:
10
+
11
+ ```mermaid
12
+ flowchart LR
13
+ P1["Phase 1: EXPAND<br/>(Zero-Downtime DDL)<br/>Add new column as NULLABLE/DEFAULT<br/>Zero breaking locks"]
14
+ P2["Phase 2: DUAL-RUN & BACKFILL<br/>(Application Rolling Update)<br/>Deploy app writing both columns<br/>Backfill historical rows<br/>Read fallback to old column"]
15
+ P3["Phase 3: CONTRACT<br/>(Cleanup DDL)<br/>Drop old column<br/>after 100% traffic migrates"]
16
+ P1 --> P2 --> P3
17
+ ```
18
+
19
+ ### Invariants:
20
+ 1. **Never Rename Columns in a Single Step**: Renaming a column causes running application instances to crash. Always expand with a new column, dual-write, backfill, and drop the old column in a subsequent release.
21
+ 2. **Concurrent Index Creation**: In PostgreSQL, never create indexes with standard blocking DDL. Always use `CREATE INDEX CONCURRENTLY` to prevent locking table writes.
22
+ 3. **Declarative Migration Tooling**: Standardize on open-source declarative migration tools (e.g. **Atlas**, **Flyway**, or **Liquibase**) that compute deterministic migration plans against production schemas.
23
+
24
+ ---
25
+
26
+ ## 2. Performance Engineering & N+1 Query Defense
27
+
28
+ A catastrophic database performance bottleneck is the **N+1 Query Problem**, where an application executes 1 query for a list and $N$ additional queries for related records in a loop.
29
+
30
+ ### Invariants:
31
+ 1. **Mandatory DataLoader / Batch Fetching**: In GraphQL resolvers, ORM mappers, or loop iterations, always batch entity queries via a DataLoader or SQL `IN (...)` batch queries:
32
+ ```typescript
33
+ // Correct: Single batched query for all tenant users
34
+ const users = await userLoader.loadMany(userIds);
35
+ ```
36
+ 2. **Composite Tenant Indexes**: In multi-tenant systems, every primary lookup index must include `tenant_id` as the leading column:
37
+ ```sql
38
+ -- Correct: Optimized for tenant-scoped date range filtering
39
+ CREATE INDEX idx_orders_tenant_created
40
+ ON orders (tenant_id, created_at DESC);
41
+ ```
42
+ 3. **Index Hygiene & Covering Indexes**: Use `EXPLAIN (ANALYZE, BUFFERS)` to verify index scans. For high-frequency queries, use covering indexes (`INCLUDE (...)`) to satisfy queries directly from index pages without heap fetches.
11
43
 
12
44
  ---
13
45
 
14
- ## 2. Table Maintenance & Bloat Defragmentation
46
+ ## 3. Connection Pooling & Resource Limits
47
+
48
+ Database connections are expensive resources requiring thread stacks and memory allocation. An uncapped connection pool will exhaust database memory and crash the server under load spikes.
15
49
 
16
- - **Online Maintenance**: Table and index space must be reclaimed using non-blocking online utilities (**`pg_repack`**, `gh-ost`, or `pt-online-schema-change`), strictly prohibiting locking full table rewrites during online hours.
17
- - **Background Autovacuum / Optimization**: Configure proactive background vacuuming and compaction thresholds to prevent transaction ID wraparound and table bloat on high-throughput tables.
50
+ ### Invariants:
51
+ 1. **Dedicated Connection Pooling**: In production, deploy a dedicated connection pooler (e.g. **PgBouncer** in transaction pooling mode for PostgreSQL, or **HikariCP** in JVM runtimes).
52
+ 2. **Connection Sizing Formula**: Size application pools conservatively using the standard Postgres sizing formula:
53
+ $$\text{connections} = ((\text{core\_count} \times 2) + \text{effective\_disk\_count})$$
54
+ Over-allocating connections (e.g., 500 connections on an 8-core server) causes severe CPU thrashing and context-switch latency.
55
+ 3. **Connection Lifecycle Limits**: Configure `max_lifetime` (e.g. 30 minutes) and `idle_timeout` (e.g. 10 minutes) to cycle stale connections and prevent socket leaks.
18
56
 
19
57
  ---
20
58
 
21
- ## 3. Least-Privilege Role Partitioning & Audit Trails
59
+ ## 4. Operational Resilience & Backup Baselines
22
60
 
23
- Enforce strict separation of database credentials across execution environments:
24
- - **`migration_deployer`**: DDL privileges (`CREATE`, `ALTER`, `DROP`) restricted to CI/CD automated migration pipelines.
25
- - **`app_runtime`**: DML privileges only (`SELECT`, `INSERT`, `UPDATE`, `DELETE`) with zero DDL or schema alteration rights.
26
- - **`analytics_readonly`**: Read-only access to sanitized views and replica nodes.
27
- - **Tamper-Proof Audit Logging**: Export schema changes, privilege grants, and sensitive queries to immutable external log sinks.
61
+ 1. **Continuous Point-In-Time Recovery (PITR)**: Production databases must configure continuous WAL (Write-Ahead Log) archiving to object storage (e.g. via `pgBackRest` or `wal-g`), enabling recovery to any arbitrary second within the retention window.
62
+ 2. **Autovacuum Tuning (PostgreSQL)**: For high-throughput transactional tables, tune autovacuum parameters to prevent table bloat and transaction ID wraparound:
63
+ ```sql
64
+ ALTER TABLE orders SET (
65
+ autovacuum_vacuum_scale_factor = 0.05,
66
+ autovacuum_vacuum_cost_limit = 1000
67
+ );
68
+ ```
69
+ 3. **Database Role Separation**: The application connection user must never connect as `postgres` or `superuser`. Create a dedicated least-privilege `app_user` granted only `DML` (`SELECT`, `INSERT`, `UPDATE`, `DELETE`) on application tables.
@@ -19,17 +19,24 @@
19
19
  - **Strategy Pattern**: Swap algorithms or execution behavior at runtime without code changes (e.g. tenant-specific pricing algorithms, shipping calculation strategies).
20
20
  - **Result / Either Pattern**: Model anticipated domain errors as explicit return values (`Result<T, E>`) rather than throwing untyped exceptions across architectural boundaries:
21
21
 
22
- ```
23
- ┌────────────────────────────────────────────────────────┐
24
- │ Universal Result Pattern Semantics │
25
- ├────────────────────────────────────────────────────────┤
26
- │ Result<T, E> = Ok(T) | Err(E) │
27
- │ │
28
- │ Rust: Result<T, DomainError> │
29
- │ Go: (T, error) │
30
- │ TypeScript: type Result<T, E> = Ok<T> | Err<E> │
31
- │ Python: Union[Success[T], Failure[E]] │
32
- └────────────────────────────────────────────────────────┘
22
+ ```mermaid
23
+ classDiagram
24
+ class Result~T_E~ {
25
+ <<Universal Semantics>>
26
+ +isOk() boolean
27
+ +isErr() boolean
28
+ +unwrap() T
29
+ +unwrapErr() E
30
+ }
31
+ class Ok~T~ {
32
+ +value: T
33
+ }
34
+ class Err~E~ {
35
+ +error: E
36
+ }
37
+ Result <|-- Ok
38
+ Result <|-- Err
39
+ note for Result "Rust: Result~T, DomainError~<br/>Go: (T, error)<br/>TypeScript: type Result~T, E~ = Ok~T~ | Err~E~<br/>Python: Union[Success[T], Failure[E]]"
33
40
  ```
34
41
 
35
42
  Domain services must return explicit Result types, compelling callers to handle failure branches deterministically.
@@ -0,0 +1,76 @@
1
+ # DevOps, CI/CD, Container Infrastructure & DevSecOps
2
+
3
+ > **Core Mandate:** Enforce trunk-based continuous integration with shift-left automated gates, minimal distroless OCI container packaging, non-root execution security, software supply chain verification (SBOM & Trivy), and zero-downtime continuous deployment.
4
+
5
+ ---
6
+
7
+ ## 1. Continuous Integration & Trunk-Based Development
8
+
9
+ CI pipelines must execute fast, deterministic, shift-left quality gates on every commit and pull request:
10
+
11
+ ```
12
+ [Local Commit] ──► [Pre-Commit Hook] ──► [Pull Request] ──► [Automated CI Gate] ──► [Merge to Main]
13
+ • Secretlint • Build Cache • Lint & Format Check
14
+ • Type Check • 100.00% Test Coverage
15
+ • DevSecOps CVE Scan
16
+ ```
17
+
18
+ ### Invariants:
19
+ 1. **Trunk-Based Development**: Feature branches must be short-lived ($\le 24$ hours) and merged into `main` continuously. Avoid long-lived feature branches that cause painful merge conflicts.
20
+ 2. **Shift-Left Automated PR Gates**: Every PR must pass automated CI checks before merge:
21
+ - Zero linter or syntax errors (`npm run lint` / `cargo clippy`).
22
+ - Strict type-checking (`tsc --noEmit` / `mypy`).
23
+ - 100.00% automated test coverage gate.
24
+ 3. **Deterministic Build Caching**: Cache dependency directories (`~/.pnpm-store`, `~/.cargo`, `~/.cache/uv`) and Docker layer caches to maintain pipeline execution times under 3 minutes.
25
+
26
+ ---
27
+
28
+ ## 2. Secure OCI Container Infrastructure
29
+
30
+ All production container images must follow strict security minimization standards:
31
+
32
+ ```dockerfile
33
+ # Multi-Stage Build Pattern
34
+ FROM node:22-alpine AS builder
35
+ WORKDIR /app
36
+ COPY package.json pnpm-lock.yaml ./
37
+ RUN corepack enable && pnpm install --frozen-lockfile
38
+ COPY . .
39
+ RUN pnpm build
40
+
41
+ # Minimal Distroless Runtime Stage
42
+ FROM gcr.io/distroless/nodejs22-debian12:nonroot
43
+ WORKDIR /app
44
+ COPY --from=builder --chown=nonroot:nonroot /app/dist ./dist
45
+ COPY --from=builder --chown=nonroot:nonroot /app/node_modules ./node_modules
46
+ USER nonroot
47
+ EXPOSE 3000
48
+ ENTRYPOINT ["node", "dist/index.js"]
49
+ ```
50
+
51
+ ### Invariants:
52
+ 1. **Multi-Stage Builds**: Build tools, package managers, and compilers must never leak into final runtime images.
53
+ 2. **Minimal Distroless / Scratch Base**: Use Google Distroless or `scratch` images. Never ship package managers (`apt`, `apk`), shells (`bash`, `sh`), or debugging utilities in production images.
54
+ 3. **Non-Root Execution**: Containers must never run as UID 0 (`root`). Always specify an unprivileged user (`USER nonroot:nonroot` or `USER 10001:10001`).
55
+ 4. **Read-Only Root Filesystem**: Configure container runtimes with `read_only: true`, mounting ephemeral tmpfs only to designated writable directories (`/tmp`).
56
+
57
+ ---
58
+
59
+ ## 3. DevSecOps & Supply Chain Security
60
+
61
+ Security checks must be embedded directly into developer workflows and automated pipelines:
62
+
63
+ 1. **Pre-Commit Secret Scanning**: Gating tools (e.g. **Secretlint**, **Gitleaks**) must block commits containing private keys, API tokens, passwords, or cloud credentials.
64
+ 2. **Software Bill of Materials (SBOM)**: Every release artifact must generate a machine-readable SBOM in **CycloneDX** or **SPDX** format (using `syft` or `cyclonedx-cli`) documenting all direct and transitive dependencies.
65
+ 3. **Automated Vulnerability Scanning**: Scan container images and dependencies with **Trivy** or **Grype** in CI. Automatically fail pipelines on unpatched `CRITICAL` or `HIGH` Common Vulnerabilities and Exposures (CVEs).
66
+
67
+ ---
68
+
69
+ ## 4. Continuous Deployment & Zero-Downtime Rollouts
70
+
71
+ 1. **Zero-Downtime Deployment Strategy**: Deployments must utilize rolling updates, canary releases, or blue/green switches. New container instances must pass readiness probes before receiving production traffic.
72
+ 2. **Container Health & Lifecycle Probes**:
73
+ - `readinessProbe`: Validates database connectivity and dependency readiness before routing HTTP traffic.
74
+ - `livenessProbe`: Detects deadlocks and restarts unresponsive containers.
75
+ - Graceful Shutdown: Handle `SIGTERM` deterministically by draining in-flight requests within a 30-second termination window.
76
+ 3. **Cryptographic Image Signing**: Sign container images with **Cosign** (Sigstore) during CI, and enforce admission controller verification in production clusters.
@@ -8,19 +8,23 @@
8
8
 
9
9
  Software engineering fails when teams jump directly into the **Solution Space** (choosing languages, frameworks, databases, and microservices) before fully defining the **Problem Space**.
10
10
 
11
- ```
12
- ┌────────────────────────────────────────────────────────────────────────┐
13
- │ THE PROBLEM SPACE │
14
- │ Business Problem ➔ Subdomains (Core/Supporting/Generic) ➔ Invariants │
15
- │ Operational Constraints: Execution target, Latency budget, GC limits │
16
- └───────────────────────────────────┬────────────────────────────────────┘
17
- │ Shapes & Dictates
18
- ▼
19
- ┌────────────────────────────────────────────────────────────────────────┐
20
- │ THE SOLUTION SPACE │
21
- │ Bounded Contexts ➔ Architectural Style (DOD, Hexagonal, Pipeline) │
22
- │ Emergent Toolchain: Programming Language, Runtime, Persistence │
23
- └────────────────────────────────────────────────────────────────────────┘
11
+ ```mermaid
12
+ flowchart TD
13
+ subgraph ProblemSpace["The Problem Space (The Essence)"]
14
+ direction TB
15
+ P1["Business Problem ➔ Subdomains (Core / Supporting / Generic) ➔ Invariants"]
16
+ P2["Operational Constraints: Execution target, Latency budget, GC limits"]
17
+ P1 --- P2
18
+ end
19
+
20
+ subgraph SolutionSpace["The Solution Space (The Accidents)"]
21
+ direction TB
22
+ S1["Bounded Contexts ➔ Architectural Style (DOD, Hexagonal, Pipeline)"]
23
+ S2["Emergent Toolchain: Programming Language, Runtime, Persistence"]
24
+ S1 --- S2
25
+ end
26
+
27
+ ProblemSpace -->|Shapes & Dictates| SolutionSpace
24
28
  ```
25
29
 
26
30
  - **The Problem Space (The Essence - Fred Brooks):** Concerns *what* problem is being solved, the entities, state transitions, and operational constraints (e.g. 16.6ms frame budget for games, zero-install browser sandbox for extensions, or ACID compliance for banking). **Zero technology, stack, or database choices are permitted in the Problem Space.**
@@ -4,9 +4,26 @@
4
4
 
5
5
  ---
6
6
 
7
- ## 1. OpenFeature Standard Architecture
7
+ ## 1. The YAGNI Gate: Environment Variables vs. Dynamic Feature Flags
8
+
9
+ Dynamic feature flag platforms (Flipt, Unleash) introduce network I/O, external infrastructure dependencies, and branching code complexity. **Never deploy a feature flag server when an environment variable or static config satisfies the requirement.**
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ subgraph FlagGate["Feature Flag YAGNI Gate"]
14
+ B1["1. Simple Baseline (Day 1)<br/>• Static environment variable (ENABLE_NEW_CHECKOUT=true)<br/>• Compile-time or build-time feature toggling<br/>• Zero external flag servers (no Flipt, Unleash, LaunchDarkly)"]
15
+ B2["2. Anti-Triggers (Forbidden)<br/>• Flags that only change during scheduled code deployments<br/>• Low-risk internal refactors covered by automated test suites<br/>• Local CLI tools, browser extensions, or single-tenant utilities"]
16
+ B3["3. The Tipping Point (Graduation)<br/>• Percentage-based canary rollouts (5% -> 25% -> 100%)<br/>• Non-engineering product/business teams require runtime toggling without deployment<br/>• Contextual tenant targeting (per subscription tier or tenant ID)<br/>• High-blast-radius integrations requiring instant kill-switches"]
17
+ B1 -->|Forbidden if static or low-risk| B2
18
+ B1 -->|Triggered by canaries or runtime targeting| B3
19
+ end
20
+ ```
21
+
22
+ ---
23
+
24
+ ## 2. OpenFeature Standard Architecture
8
25
 
9
- Utilize open-source `@openfeature/server-sdk` with open-source providers (Flipt or Unleash):
26
+ When the tipping point is reached, utilize open-source `@openfeature/server-sdk` with open-source providers (Flipt or Unleash):
10
27
 
11
28
  ```typescript
12
29
  import { OpenFeature, Client } from '@openfeature/server-sdk';
@@ -18,7 +35,7 @@ export const featureClient: Client = OpenFeature.getClient();
18
35
 
19
36
  ---
20
37
 
21
- ## 2. Contextual Tenant Targeting
38
+ ## 3. Contextual Tenant Targeting
22
39
 
23
40
  Pass tenant identity and contextual attributes during evaluation:
24
41
 
@@ -36,7 +53,7 @@ const isEnabled = await featureClient.getBooleanValue(
36
53
 
37
54
  ---
38
55
 
39
- ## 3. Flag Lifecycle Governance
56
+ ## 4. Flag Lifecycle Governance
40
57
 
41
58
  - **Emergency Kill Switches**: Every high-risk feature or third-party integration must be wrapped in a flag that can immediately disable functionality without code redeployment.
42
59
  - **Retirement Mandate**: When a feature is 100% rolled out for > 30 days, author a task to purge the flag and its dead code branches.
@@ -0,0 +1,157 @@
1
+ # Frontend Architecture & Client State Management
2
+
3
+ > **Core Mandate:** Enforce production-grade client architecture: accessible headless component primitives, WCAG 2.2 Level AA compliance, asynchronous server-state cache synchronization and deduplication, declarative contract schema form validation, bidirectional URL navigation synchronization, explicit 5-tier state separation, and symmetrical design tokens.
4
+
5
+ ---
6
+
7
+ ## 1. The YAGNI Gate: Semantic Markup & Headless Primitives vs. Premature Sprawl
8
+
9
+ Frontend engineering is frequently derailed by two opposing anti-patterns: **reinventing the wheel** (hand-rolling custom dialogs and bespoke CSS architectures) or **premature framework sprawl** (installing heavy global state machines for simple data flows).
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ subgraph Gate ["Frontend Architecture YAGNI Gate"]
14
+ B1["1. SIMPLE BASELINE (Day 1)"]
15
+ B1_D["• Semantic HTML/markup styled with utility classes.<br/>• Battle-tested accessible headless primitives (Radix, Melt, Kobalte, PrimeVue).<br/>• Zero bespoke CSS architectures, unstyled div modals, or Redux."]
16
+
17
+ B2["2. ANTI-TRIGGERS (Strictly Forbidden)"]
18
+ B2_D["• Headless backends, REST/gRPC microservices, or cloud workers.<br/>• Terminal CLI utilities, embedded libraries, or game engines.<br/>• Monolithic global state stores (Redux, MobX, Pinia) before separating server cache."]
19
+
20
+ B3["3. THE TIPPING POINT (Graduation Threshold)"]
21
+ B3_D["• Dynamic client interfaces with asynchronous server data fetching.<br/>• Multi-step declarative form submissions and complex workflows.<br/>• Strict WCAG 2.2 AA accessibility, focus trapping, and keyboard navigation."]
22
+
23
+ B1 --- B1_D
24
+ B2 --- B2_D
25
+ B3 --- B3_D
26
+ end
27
+ ```
28
+
29
+ ---
30
+
31
+ ## 2. The Asymmetry Law: Outside-In Discovery vs. Inside-Out Execution
32
+
33
+ A fundamental architectural question is: **Does the User Interface dictate Business Logic, or does Business Logic dictate the UI?**
34
+
35
+ The answer is governed by the **Outside-In Discovery vs. Inside-Out Execution Asymmetry**:
36
+
37
+ ```mermaid
38
+ flowchart LR
39
+ subgraph Discovery ["Outside-In Discovery (Phase 1 & 2)"]
40
+ UI["User Interface & Interaction Model<br/>(Web GUI, Mobile, or Terminal CLI)"]
41
+ UC["Inbound Driving Port<br/>(Use Case / Command DTO)"]
42
+ UI -->|"Discovers Required Capabilities"| UC
43
+ end
44
+
45
+ subgraph Execution ["Inside-Out Execution (Phase 3 & 4)"]
46
+ DM["Domain Core & Invariants<br/>(100% UI-Agnostic Rules & State Machines)"]
47
+ AD["Outbound Driven Adapters<br/>(Database, Email, External Services)"]
48
+ UC -->|"Executes Isolated Logic"| DM
49
+ DM -->|"Persists / Notifies"| AD
50
+ end
51
+ ```
52
+
53
+ ### 1. Outside-In Discovery (Why Interaction Must Be Refined Early)
54
+ - The user's operational mental model, workflow steps, and interaction touchpoints (whether Web forms, CLI flags, or API endpoints) **guide the discovery of system capabilities**.
55
+ - If business logic is authored in a vacuum without interaction analysis, engineers build speculative methods and database models that do not align with user journeys (**The Anemic Core Antipattern**).
56
+ - *Mandate:* In Phase 1 (Requirements) and Phase 2 (Domain Analysis), interaction models and wireframe workflows must be refined early via [`product-analyst`](../../.agents/skills/product-analyst/SKILL.md) and [`ui_ux_architecture.md`](./ui_ux_architecture.md).
57
+
58
+ ### 2. Inside-Out Execution (Why Domain Logic Remains Pure)
59
+ - Once discovered, **business invariants are 100% decoupled from the UI**.
60
+ - A business rule (e.g. *"An invoice cannot be paid twice"*, *"Discount cannot exceed 50%"*) must never live in a React `onClick` handler, a component hook, or a CLI flag parser (**The Smart UI Antipattern**).
61
+ - The presentation layer merely parses user interaction into a plain **Command DTO** and calls an **Application Use Case** (Driving Port).
62
+ - If the Web UI is replaced with a CLI or a background job, the core domain logic requires **zero modifications**.
63
+
64
+ ### 3. What If a Project Has No UI? (Headless Topologies)
65
+ - For Headless Backends, Daemon Workers, and Embedded Systems:
66
+ - The **API Schema (OpenAPI / gRPC Protobuf) or Function Signature IS the UI**.
67
+ - For a CLI Utility, the **Command Pipeline (flags, stdin/stdout, exit codes)** IS the UI.
68
+ - The principle remains identical: the external interface defines the boundary contract, while the internal engine enforces pure invariants.
69
+
70
+ ---
71
+
72
+ ## 3. Component Primitives, Headless Accessibility & WCAG 2.2 Standards
73
+
74
+ - **Accessible Headless Primitives**: All interactive UI components (dialogs, dropdowns, selects, tabs, tooltips, popovers) must decouple behavioral accessibility (focus trapping, keyboard navigation, ARIA states) from visual presentation using headless primitives:
75
+ - *React:* `@radix-ui` / `shadcn/ui` in `@/components/ui/`
76
+ - *Vue:* `radix-vue` / `shadcn-vue` or `primevue`
77
+ - *Svelte:* `melt-ui` / `bits-ui`
78
+ - *Solid:* `@kobalte/core`
79
+ - *Angular:* `@angular/cdk/a11y`
80
+ - **Zero Unstyled Raw Elements**: Never create unstyled raw HTML modals, dropdowns, or custom select tags using raw `<div>` tags and ad-hoc mouse-only click handlers.
81
+ - **Focus Management & Trapping**:
82
+ - Modal dialogs must trap keyboard focus within the dialog container while open.
83
+ - Closing a dialog must return keyboard focus deterministically to the triggering element.
84
+ - **Visible Focus Indicators**: Never remove default outline rings (`outline: none`) without providing an explicit, high-contrast replacement (`focus-visible:ring-2 focus-visible:ring-offset-2`).
85
+ - **Dynamic Content & ARIA Live Regions**:
86
+ - Asynchronous notifications, toast alerts, and status updates must use `role="status"` or `aria-live="polite"` so screen readers announce changes without interrupting the user.
87
+ - Critical error alerts must use `role="alert"` or `aria-live="assertive"`.
88
+ - **Strict Prohibition of Native Dialogs**: Browser-native `window.alert()` and `window.confirm()` are strictly forbidden. Use accessible headless dialogs (`<ConfirmDialog />`).
89
+ - **Utility Styling & Class Merging (`cn` helper)**: Combine utility classes using deterministic class merging (e.g., `clsx` and `tailwind-merge` via `cn(...)`) to allow clean prop overrides and consistent theming.
90
+
91
+ ---
92
+
93
+ ## 4. Server-State Cache Synchronization & Invalidation
94
+
95
+ - **Decoupling Remote Cache from Local State**: Server state (owned remotely, asynchronous, shared across clients) must never be treated as local synchronous client state.
96
+ - **Mandatory Cache Synchronization Engine**: Asynchronous data fetching, caching, deduplication, and background revalidation must use a dedicated cache synchronization manager (e.g., TanStack Query, SWR, or RTK Query in React; Pinia Colada or VueUse `useFetch` in Vue; Superforms or SvelteKit load functions in Svelte; Angular Signals with HttpClient).
97
+ - **Elimination of Raw Lifecycle Fetch Loops**:
98
+ - *Anti-Pattern:* Uncoordinated manual fetching in component lifecycles (`useEffect(() => { fetch().then(...) })`, `onMounted`, `ngOnInit`) with hand-rolled `isLoading` and `error` boolean states.
99
+ - *Standard Pattern (Query Hook / Cache Invalidation):*
100
+ ```tsx
101
+ const { data: resources, isLoading, error } = useQuery({
102
+ queryKey: ['resources', tenantId],
103
+ queryFn: () => api.getResources(tenantId),
104
+ });
105
+ ```
106
+ - **Declarative Mutations & Cache Invalidation**:
107
+ - Mutations must declare side-effects that explicitly invalidate affected cache keys rather than imperatively splicing local component state arrays:
108
+ ```tsx
109
+ const queryClient = useQueryClient();
110
+ const createResourceMutation = useMutation({
111
+ mutationFn: (newResource: CreateResourceInput) => api.createResource(newResource),
112
+ onSuccess: () => {
113
+ queryClient.invalidateQueries({ queryKey: ['resources'] });
114
+ },
115
+ });
116
+ ```
117
+ - **Hierarchical Query Keys**: Format query keys hierarchically as structured tuples: `['entity', id, ...filters]`, e.g., `['orders', orderId]`, `['users', tenantId]`.
118
+
119
+ ---
120
+
121
+ ## 5. Form State Management & Fail-Fast Schema Validation
122
+
123
+ - **Mandatory Schema Validation**: Every form submission must be validated against a formal declarative schema (Zod, Valibot, standard-schema, or framework validator) that mirrors shared DTO/input contracts.
124
+ - **Dedicated Form State Engines**: Use dedicated form engines (React Hook Form, TanStack Form, VeeValidate, Superforms, Angular Reactive Forms) that track field dirty states, touched states, and asynchronous validation without triggering full component tree re-renders.
125
+ - **Zero Unvalidated Multi-Field Objects**:
126
+ - *Anti-Pattern:* Unvalidated ad-hoc dictionary state (`useState({ name: '', email: '' })`) with manual string checking in submit handlers.
127
+ - *Standard Pattern:*
128
+ ```tsx
129
+ const form = useForm<CreateUserInput>({
130
+ resolver: zodResolver(createUserSchema),
131
+ defaultValues: { name: '', email: '' },
132
+ });
133
+ ```
134
+ - **Accessible Error Linking**: Form inputs must bind validation errors to `aria-invalid="true"` and `aria-describedby="<field>-error"`. Every input must have an associated semantic `<label>`.
135
+
136
+ ---
137
+
138
+ ## 6. The 5-Tier State Hierarchy & Bidirectional URL Navigation
139
+
140
+ Never dump all application state into a single global state container. Enforce strict categorical separation across 5 distinct lifecycles:
141
+
142
+ 1. **Server State (Remote Cache)**: Managed exclusively by the query cache engine; invalidated by resource keys.
143
+ 2. **URL State (Navigation / Search / Pagination / Filters)**:
144
+ - Must synchronize bidirectionally with URL search parameters (`useSearchParams`) to ensure deep linkability, bookmarkability, and seamless browser history (back/forward) navigation.
145
+ - Standard format: `?tab=security&page=2&limit=25&sort=createdAt&order=desc&status=ACTIVE`.
146
+ - Modals and drawers representing actionable entities must synchronize with the URL (e.g. `?modal=edit-user&userId=123`).
147
+ 3. **Form State (Transient Edits)**: Managed by form validation engines; discarded after submission or reset.
148
+ 4. **Local Component State (Ephemeral UI)**: Managed by primitive local component state (`useState`, `ref`, `$state`) strictly for local UI toggles (dropdown open, accordion expanded, hover).
149
+ 5. **Global Application State (Session / Context)**: Managed by lightweight client stores (Zustand, Pinia, Context, Signals) strictly for cross-cutting session data (current user, tenant context, active feature flags).
150
+ 6. **Data Grids & Large Tables**: When building sortable, paginated, or virtualized tables, standardize on headless table engines (TanStack Table, AG Grid) with row virtualization for datasets exceeding 100 rows.
151
+
152
+ ---
153
+
154
+ ## 7. Theme Architecture & Symmetrical Design Tokens
155
+
156
+ - **Symmetric Design Tokens**: Ensure foundational CSS variables (`--background`, `--foreground`, `--card`, `--border`, `--popover`) are symmetrically declared across `:root` and `.dark`. Omitted root tokens in `.dark` result in unstyled backgrounds and illegible text when switching themes.
157
+ - **System Preference Detection & Reactive Synchronization**: `ThemeProvider` implementations must listen to `window.matchMedia('(prefers-color-scheme: dark)')` with dynamic event listeners so OS appearance toggles seamlessly propagate in real-time, and synchronize `document.documentElement.style.colorScheme = resolvedTheme` to ensure browser-native elements (scrollbars, input widgets) match the active theme.
@@ -0,0 +1,98 @@
1
+ # Multi-Tenancy Architecture, Isolation & Extensibility
2
+
3
+ > **Core Mandate:** Enforce tenant context resolution from trusted cryptographic tokens, strict data isolation across the 4 tenancy models, leak-proof PostgreSQL Row-Level Security (RLS), and YAGNI-gated tenant extensibility (dynamic JSON schemas and sandboxed pluggable logic).
4
+
5
+ ---
6
+
7
+ ## 1. The Multi-Tenancy YAGNI Gate: Single-Tenant vs. Shared SaaS
8
+
9
+ Multi-tenancy introduces significant operational complexity: tenant routing, cross-tenant data leak risks, noisy neighbor resource starvation, and complex database migrations. **Never force multi-tenant abstractions onto applications that execute in single-tenant boundaries.**
10
+
11
+ ```mermaid
12
+ flowchart TD
13
+ subgraph MultiTenancyGate["Multi-Tenancy YAGNI Gate"]
14
+ B1["1. Simple Baseline (Day 1)<br/>• Single-tenant application architecture<br/>• Standard database tables without tenant foreign keys<br/>• Zero RLS policies, tenant interceptors, or dynamic schemas"]
15
+ B2["2. Anti-Triggers (Forbidden)<br/>• Single-tenant on-premise deployments or dedicated instances<br/>• Internal employee enterprise tools, developer CLIs, or games<br/>• Early-stage prototypes validating core domain logic"]
16
+ B3["3. The Tipping Point (Graduation)<br/>• Multi-tenant B2B SaaS where independent organizations share infrastructure<br/>• Strict legal, SOC 2, and regulatory mandates prohibiting cross-tenant data leakage"]
17
+ B1 -->|Forbidden if single-tenant| B2
18
+ B1 -->|Triggered by B2B SaaS requirements| B3
19
+ end
20
+ ```
21
+
22
+ ---
23
+
24
+ ## 2. Tenant Context Resolution
25
+
26
+ Tenant identity must be resolved at the edge/gateway from **cryptographically verified session context**, never from spoofable client input:
27
+
28
+ ```mermaid
29
+ flowchart LR
30
+ Req["Incoming Request"] --> Auth["Auth Middleware<br/>Extract Verified tenantId from JWT"]
31
+ Auth --> Ctx["AsyncLocalStorage / Context"]
32
+ Ctx --> DB["Database Connection<br/>SET LOCAL app.current_tenant_id"]
33
+ Ctx --> Audit["Audit / Event Log<br/>Tagged with tenantId"]
34
+ ```
35
+
36
+ ### Invariants:
37
+ 1. **Never Trust Raw Query/Body Parameters**: Never accept `?tenantId=...` or `{ tenantId: "..." }` on public mutations without validating that the authenticated session owns that tenant.
38
+ 2. **Ambient Context Propagation**: Bind the resolved `tenantId` to an ambient request context (e.g. `AsyncLocalStorage` in Node, `ThreadLocal` in Java, `context.Context` in Go) to prevent passing tenant IDs manually through every service layer.
39
+
40
+ ---
41
+
42
+ ## 3. The 4 Universal Data Isolation Models
43
+
44
+ Choose the isolation model matching your security classification and cost profile:
45
+
46
+ | Model | Isolation Mechanism | Operational Trade-off | Compliance Target |
47
+ |---|---|---|---|
48
+ | **1. Pooled with RLS** | Shared DB, shared schema; tables partitioned by `tenant_id` + Postgres RLS. | Lowest infrastructure cost, highest engineering rigor required. | Standard B2B SaaS, SOC 2 Type II. |
49
+ | **2. Silo Schema** | Shared DB, separate database schema per tenant (`tenant_acme.*`). | High isolation; complex schema migrations across hundreds of schemas. | Regulated SaaS, HIPAA, FinTech. |
50
+ | **3. Silo Database** | Separate physical or logical database instance per tenant. | Highest cost and isolation; zero cross-tenant blast radius. | Enterprise Dedicated, PCI-DSS Level 1. |
51
+ | **4. App-Level Interceptor** | Shared DB, ORM/query builder automatically appends `WHERE tenant_id = :id`. | Brittle; human error in ad-hoc raw SQL queries bypasses isolation. | Forbidden for high-security applications. |
52
+
53
+ ---
54
+
55
+ ## 4. PostgreSQL Row-Level Security (RLS) Invariants
56
+
57
+ When using **Model 1 (Pooled with RLS)**, enforce data isolation at the database engine level so that even a buggy or malicious application query cannot access another tenant's rows:
58
+
59
+ ### 1. Dual-Lock Table Setup
60
+ Every table containing tenant-scoped data must enable and force RLS:
61
+ ```sql
62
+ ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
63
+ ALTER TABLE orders FORCE ROW LEVEL SECURITY;
64
+ ```
65
+ *(The `FORCE` clause ensures that table owners and superusers are also bound by the policy).*
66
+
67
+ ### 2. Session Context Binding
68
+ The application connection pool must initialize the tenant session variable inside every transactional checkout:
69
+ ```sql
70
+ -- Executed inside transaction before running queries
71
+ SELECT set_config('app.current_tenant_id', :tenantId, true);
72
+ ```
73
+
74
+ ### 3. Declarative Tenant Isolation Policy
75
+ ```sql
76
+ CREATE POLICY tenant_isolation_policy ON orders
77
+ AS RESTRICTIVE
78
+ FOR ALL
79
+ TO application_user
80
+ USING (tenant_id = NULLIF(current_setting('app.current_tenant_id', true), '')::UUID)
81
+ WITH CHECK (tenant_id = NULLIF(current_setting('app.current_tenant_id', true), '')::UUID);
82
+ ```
83
+
84
+ ---
85
+
86
+ ## 5. Advanced Tenant Extensibility (YAGNI Gated)
87
+
88
+ ### 5.1. Dynamic Schemas (Runtime Custom Fields)
89
+ - **Tipping Point:** External enterprise tenants require self-service custom fields without engineering running relational DDL migrations.
90
+ - **Hybrid Storage Pattern:** Core relational columns for shared invariants + `custom_attributes JSONB` validated against **JSON Schema Draft 2020-12** stored per tenant.
91
+ - **Fail-Fast Schema Validation:** Custom field inputs must be validated against the tenant's compiled JSON schema before database persistence.
92
+
93
+ ### 5.2. Pluggable Tenant Logic (Sandboxed Scripting)
94
+ - **Tipping Point:** Enterprise tenants require custom business logic (tax calculation, approval routing) executed at runtime.
95
+ - **Zero Raw `eval()`**: Never execute tenant code via raw `eval()`, Python `exec()`, or NodeJS VM isolates.
96
+ - **Safe Sandboxing**:
97
+ - *Simple Expressions:* Use **Common Expression Language (CEL)** (Google) for safe, deterministic boolean and mathematical evaluation.
98
+ - *Complex Logic:* Compile tenant extension plugins to **WebAssembly (Wasm)** executed via Wasmer or Wasmtime with strict CPU time and memory quotas.
@@ -41,20 +41,12 @@ The only vehicle through which a team delivers actual product value is a usable,
41
41
 
42
42
  The OKR framework connects overarching strategic vision to sprint execution and product backlog ordering.
43
43
 
44
- ```
45
- Company Vision & Strategy
46
- │
47
- ▼
48
- Strategic OKRs (Annual / Quarterly)
49
- │
50
- ▼
51
- Product Goal (Long-Term Commitment)
52
- │
53
- ▼
54
- Product Backlog (Emergent, Ordered PBIs)
55
- │
56
- ▼
57
- Sprint Goal (Tactical Increment)
44
+ ```mermaid
45
+ flowchart TD
46
+ V["Company Vision & Strategy"] --> OKR["Strategic OKRs (Annual / Quarterly)"]
47
+ OKR --> PG["Product Goal (Long-Term Commitment)"]
48
+ PG --> PB["Product Backlog (Emergent, Ordered PBIs)"]
49
+ PB --> SG["Sprint Goal (Tactical Increment)"]
58
50
  ```
59
51
 
60
52
  ### Anatomy of an OKR
@@ -111,19 +103,22 @@ A collaborative prioritization exercise where stakeholders are allocated a const
111
103
 
112
104
  Following Gunther Verheyen's backlog topology, the Product Backlog serves as an **emergent, living roadmap**:
113
105
 
114
- ```
115
- ▲ Finer Granularity (Top)
116
- │ [ PBI 1: Sprintable, vertically sliced, clear DoD & Gherkin ]
117
- │ [ PBI 2: High priority, well-understood, estimated ]
118
- │ [ PBI 3: Actionable, small, customer value clear ]
119
- │
120
- │ Medium Granularity (Middle)
121
- │ [ PBI 4: Candidate for next period, coarse slice ]
122
- │ [ PBI 5: Alternative approach under evaluation ]
123
- │
124
- ▼ Coarser Granularity (Bottom)
125
- [ PBI 6: Long-term idea, future capability ]
126
- [ PBI 7: Raw thought, exploratory concept ]
106
+ ```mermaid
107
+ flowchart TD
108
+ subgraph Top["Finer Granularity (Top of Backlog)"]
109
+ P1["PBI 1: Sprintable, vertically sliced, clear DoD & Gherkin"]
110
+ P2["PBI 2: High priority, well-understood, estimated"]
111
+ P3["PBI 3: Actionable, small, customer value clear"]
112
+ end
113
+ subgraph Middle["Medium Granularity (Middle)"]
114
+ P4["PBI 4: Candidate for next period, coarse slice"]
115
+ P5["PBI 5: Alternative approach under evaluation"]
116
+ end
117
+ subgraph Bottom["Coarser Granularity (Bottom)"]
118
+ P6["PBI 6: Long-term idea, future capability"]
119
+ P7["PBI 7: Raw thought, exploratory concept"]
120
+ end
121
+ Top --> Middle --> Bottom
127
122
  ```
128
123
 
129
124
  ### Rules of Progressive Elaboration