dhurandhar 1.0.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.
- package/.dhurandhar-session-start.md +242 -0
- package/LICENSE +21 -0
- package/README.md +416 -0
- package/docs/ARCHITECTURE_V2.md +249 -0
- package/docs/DECISION_REGISTRY.md +357 -0
- package/docs/IMPLEMENTATION_PERSONAS.md +406 -0
- package/docs/PLUGGABLE_STRATEGIES.md +439 -0
- package/docs/SYSTEM_OBSERVER.md +433 -0
- package/docs/TEST_FIRST_AGILE.md +359 -0
- package/docs/architecture.md +279 -0
- package/docs/engineering-first-philosophy.md +263 -0
- package/docs/getting-started.md +218 -0
- package/docs/module-development.md +323 -0
- package/docs/strategy-example.md +299 -0
- package/docs/test-first-example.md +392 -0
- package/package.json +79 -0
- package/src/core/README.md +92 -0
- package/src/core/agent-instructions/backend-developer.md +412 -0
- package/src/core/agent-instructions/devops-engineer.md +372 -0
- package/src/core/agent-instructions/dhurandhar-council.md +547 -0
- package/src/core/agent-instructions/edge-case-hunter.md +322 -0
- package/src/core/agent-instructions/frontend-developer.md +494 -0
- package/src/core/agent-instructions/lead-system-architect.md +631 -0
- package/src/core/agent-instructions/system-observer.md +319 -0
- package/src/core/agent-instructions/test-architect.md +284 -0
- package/src/core/module.yaml +54 -0
- package/src/core/schemas/design-module-schema.yaml +995 -0
- package/src/core/schemas/system-design-map-schema.yaml +324 -0
- package/src/modules/example/README.md +130 -0
- package/src/modules/example/module.yaml +252 -0
- package/tools/cli/commands/audit.js +267 -0
- package/tools/cli/commands/config.js +113 -0
- package/tools/cli/commands/context.js +170 -0
- package/tools/cli/commands/decisions.js +398 -0
- package/tools/cli/commands/entity.js +218 -0
- package/tools/cli/commands/epic.js +125 -0
- package/tools/cli/commands/install.js +172 -0
- package/tools/cli/commands/module.js +109 -0
- package/tools/cli/commands/service.js +167 -0
- package/tools/cli/commands/story.js +225 -0
- package/tools/cli/commands/strategy.js +294 -0
- package/tools/cli/commands/test.js +277 -0
- package/tools/cli/commands/validate.js +107 -0
- package/tools/cli/dhurandhar.js +212 -0
- package/tools/lib/config-manager.js +170 -0
- package/tools/lib/filesystem.js +126 -0
- package/tools/lib/module-installer.js +61 -0
- package/tools/lib/module-manager.js +149 -0
- package/tools/lib/sdm-manager.js +982 -0
- package/tools/lib/test-engine.js +255 -0
- package/tools/lib/test-templates/api-client.template.js +100 -0
- package/tools/lib/test-templates/vitest.config.template.js +37 -0
- package/tools/lib/validators/config-validator.js +113 -0
- package/tools/lib/validators/module-validator.js +137 -0
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# System Design Map (SDM) Schema
|
|
2
|
+
# Cross-session persistence format for architectural state
|
|
3
|
+
# Purpose: Enable instant context rehydration without re-discovery
|
|
4
|
+
|
|
5
|
+
schema_version: "1.0"
|
|
6
|
+
name: "system-design-map"
|
|
7
|
+
description: "Persistent architectural state for context rehydration"
|
|
8
|
+
|
|
9
|
+
# The SDM is stored at project root as SYSTEM_DESIGN_MAP.yaml
|
|
10
|
+
# Agents read this first to understand current architecture
|
|
11
|
+
|
|
12
|
+
structure:
|
|
13
|
+
# Metadata
|
|
14
|
+
metadata:
|
|
15
|
+
project_name: string
|
|
16
|
+
version: string
|
|
17
|
+
last_updated: timestamp
|
|
18
|
+
architecture_type: string # monolith, microservices, serverless, hybrid
|
|
19
|
+
|
|
20
|
+
# Tech Stack Summary
|
|
21
|
+
tech_stack:
|
|
22
|
+
languages: [string]
|
|
23
|
+
frameworks: [string]
|
|
24
|
+
databases: [string]
|
|
25
|
+
infrastructure: [string]
|
|
26
|
+
|
|
27
|
+
# User Types (who uses the system)
|
|
28
|
+
user_types:
|
|
29
|
+
- role: string
|
|
30
|
+
permissions: [string]
|
|
31
|
+
authentication: string
|
|
32
|
+
|
|
33
|
+
# Entities (data model)
|
|
34
|
+
entities:
|
|
35
|
+
- name: string
|
|
36
|
+
attributes:
|
|
37
|
+
- name: string
|
|
38
|
+
type: string
|
|
39
|
+
constraints: [string]
|
|
40
|
+
relationships:
|
|
41
|
+
- type: one_to_one | one_to_many | many_to_one | many_to_many
|
|
42
|
+
target: string
|
|
43
|
+
foreign_key: string
|
|
44
|
+
|
|
45
|
+
# Services (microservices or modules)
|
|
46
|
+
services:
|
|
47
|
+
- name: string
|
|
48
|
+
scope: string # what it does
|
|
49
|
+
tech_stack:
|
|
50
|
+
language: string
|
|
51
|
+
framework: string
|
|
52
|
+
database: string
|
|
53
|
+
api:
|
|
54
|
+
type: rest | grpc | graphql
|
|
55
|
+
base_path: string
|
|
56
|
+
port: integer
|
|
57
|
+
dependencies: [string] # other services
|
|
58
|
+
data_access: [string] # entities
|
|
59
|
+
|
|
60
|
+
# Service Communication (how services talk)
|
|
61
|
+
communication:
|
|
62
|
+
- from: string # service name
|
|
63
|
+
to: string # service name
|
|
64
|
+
protocol: string # http, grpc, message_queue, event_bus
|
|
65
|
+
pattern: string # sync, async, pub_sub
|
|
66
|
+
|
|
67
|
+
# Infrastructure (deployment & ops)
|
|
68
|
+
infrastructure:
|
|
69
|
+
deployment_target: string # docker, kubernetes, aws_lambda, etc.
|
|
70
|
+
components:
|
|
71
|
+
- type: string # load_balancer, cache, message_queue, etc.
|
|
72
|
+
name: string
|
|
73
|
+
technology: string # nginx, redis, rabbitmq, etc.
|
|
74
|
+
|
|
75
|
+
# Build & Deployment
|
|
76
|
+
build_config:
|
|
77
|
+
- service: string
|
|
78
|
+
build_tool: string # make, npm, cargo, gradle, etc.
|
|
79
|
+
dockerfile: boolean
|
|
80
|
+
ci_cd: string # github_actions, gitlab_ci, etc.
|
|
81
|
+
|
|
82
|
+
# Technical Decision Registry - Centralized "Stock of Decisions"
|
|
83
|
+
decision_registry:
|
|
84
|
+
naming_conventions:
|
|
85
|
+
case_styles:
|
|
86
|
+
classes: PascalCase | camelCase | snake_case
|
|
87
|
+
functions: PascalCase | camelCase | snake_case
|
|
88
|
+
variables: PascalCase | camelCase | snake_case
|
|
89
|
+
constants: SCREAMING_SNAKE_CASE | PascalCase
|
|
90
|
+
database_tables: snake_case | PascalCase
|
|
91
|
+
database_columns: snake_case | camelCase
|
|
92
|
+
api_endpoints: kebab-case | snake_case
|
|
93
|
+
|
|
94
|
+
file_patterns:
|
|
95
|
+
components: string
|
|
96
|
+
services: string
|
|
97
|
+
models: string
|
|
98
|
+
tests: string
|
|
99
|
+
|
|
100
|
+
prefixes_suffixes:
|
|
101
|
+
interfaces: string
|
|
102
|
+
abstract_classes: string
|
|
103
|
+
test_functions: string
|
|
104
|
+
private_methods: string
|
|
105
|
+
|
|
106
|
+
design_patterns:
|
|
107
|
+
data_access: repository_pattern | active_record | data_mapper
|
|
108
|
+
service_layer: service_classes | function_modules | handlers_only
|
|
109
|
+
dependency_injection: constructor_injection | property_injection | none
|
|
110
|
+
validation: dto_validation | middleware_validation | domain_validation
|
|
111
|
+
cqrs: boolean
|
|
112
|
+
event_sourcing: boolean
|
|
113
|
+
domain_driven_design: boolean
|
|
114
|
+
service_specific_patterns:
|
|
115
|
+
- service: string
|
|
116
|
+
pattern: string
|
|
117
|
+
rationale: string
|
|
118
|
+
|
|
119
|
+
error_response_standards:
|
|
120
|
+
error_code_mapping:
|
|
121
|
+
validation_error: integer (HTTP status)
|
|
122
|
+
authentication_error: integer
|
|
123
|
+
authorization_error: integer
|
|
124
|
+
not_found_error: integer
|
|
125
|
+
conflict_error: integer
|
|
126
|
+
internal_error: integer
|
|
127
|
+
|
|
128
|
+
response_envelope:
|
|
129
|
+
success_format: string (JSON template)
|
|
130
|
+
error_format: string (JSON template)
|
|
131
|
+
include_request_id: boolean
|
|
132
|
+
include_timestamp: boolean
|
|
133
|
+
|
|
134
|
+
error_detail_level: minimal | standard | verbose | debug_only
|
|
135
|
+
|
|
136
|
+
observability_standards:
|
|
137
|
+
logging:
|
|
138
|
+
levels: [string] (e.g., DEBUG, INFO, WARN, ERROR)
|
|
139
|
+
structured_logging: boolean
|
|
140
|
+
mandatory_fields: [string] (e.g., trace_id, service_name)
|
|
141
|
+
sensitive_data_masking: boolean
|
|
142
|
+
|
|
143
|
+
tracing:
|
|
144
|
+
trace_id_header: string (e.g., X-Trace-ID)
|
|
145
|
+
correlation_id_header: string (e.g., X-Correlation-ID)
|
|
146
|
+
span_naming_format: string
|
|
147
|
+
|
|
148
|
+
metrics:
|
|
149
|
+
naming_format: string (e.g., service_metric_unit)
|
|
150
|
+
mandatory_labels: [string] (e.g., service, environment)
|
|
151
|
+
latency_buckets: [number]
|
|
152
|
+
|
|
153
|
+
api_standards:
|
|
154
|
+
versioning_strategy: url_path | header | query_param
|
|
155
|
+
version_format: string (e.g., v1, 1.0)
|
|
156
|
+
pagination:
|
|
157
|
+
style: offset_limit | cursor | page_number
|
|
158
|
+
default_page_size: integer
|
|
159
|
+
max_page_size: integer
|
|
160
|
+
rate_limiting:
|
|
161
|
+
enabled: boolean
|
|
162
|
+
default_limit: integer
|
|
163
|
+
window: string
|
|
164
|
+
|
|
165
|
+
code_quality_standards:
|
|
166
|
+
test_coverage_minimum: integer (percentage)
|
|
167
|
+
documentation_required: boolean
|
|
168
|
+
linting_rules: string
|
|
169
|
+
code_review_required: boolean
|
|
170
|
+
|
|
171
|
+
# Technical Strategies - Pluggable Architectural Patterns
|
|
172
|
+
technical_strategies:
|
|
173
|
+
persistence:
|
|
174
|
+
model: database_per_service | shared_database | hybrid | event_sourcing
|
|
175
|
+
constraints: [string]
|
|
176
|
+
database_assignments:
|
|
177
|
+
service-name: database-instance
|
|
178
|
+
|
|
179
|
+
state_management:
|
|
180
|
+
caching_layer: distributed_redis | local_in_memory | sidecar_cache | cdn_edge | none
|
|
181
|
+
session_storage: redis_distributed | database | jwt_stateless | sticky_sessions
|
|
182
|
+
cache_invalidation: ttl_based | event_driven | manual | write_through
|
|
183
|
+
|
|
184
|
+
communication:
|
|
185
|
+
primary_pattern: synchronous_rest | asynchronous_events | hybrid | grpc_streaming
|
|
186
|
+
event_bus:
|
|
187
|
+
technology: kafka | rabbitmq | aws_sns_sqs | redis_streams | nats
|
|
188
|
+
topics_or_queues: [string]
|
|
189
|
+
message_format: json | avro | protobuf
|
|
190
|
+
api_gateway:
|
|
191
|
+
technology: nginx | kong | aws_api_gateway | envoy
|
|
192
|
+
features: [string]
|
|
193
|
+
|
|
194
|
+
deployment:
|
|
195
|
+
orchestration: kubernetes | docker_swarm | ecs | serverless
|
|
196
|
+
scaling_strategy: horizontal_pod_autoscaling | vertical_scaling | manual
|
|
197
|
+
service_mesh:
|
|
198
|
+
enabled: boolean
|
|
199
|
+
technology: istio | linkerd | consul | none
|
|
200
|
+
|
|
201
|
+
observability:
|
|
202
|
+
logging: centralized_elk | cloudwatch | datadog | loki
|
|
203
|
+
metrics: prometheus | datadog | cloudwatch
|
|
204
|
+
tracing: jaeger | zipkin | aws_xray | datadog_apm
|
|
205
|
+
distributed_tracing: boolean
|
|
206
|
+
|
|
207
|
+
security:
|
|
208
|
+
authentication: jwt_centralized | oauth2_delegated | mtls | api_keys
|
|
209
|
+
authorization: rbac | abac | policy_engine_opa | service_level
|
|
210
|
+
secrets_management: vault | aws_secrets_manager | kubernetes_secrets
|
|
211
|
+
|
|
212
|
+
resilience:
|
|
213
|
+
circuit_breaker: boolean
|
|
214
|
+
retry_strategy: exponential_backoff | fixed_delay | none
|
|
215
|
+
timeout_policy: aggressive_5s | moderate_30s | lenient_60s
|
|
216
|
+
bulkhead_isolation: boolean
|
|
217
|
+
|
|
218
|
+
# Agile Blueprint - Test-First Decomposition
|
|
219
|
+
agile_blueprint:
|
|
220
|
+
epics:
|
|
221
|
+
- id: string # EPIC-001
|
|
222
|
+
name: string # "User Authentication & Authorization"
|
|
223
|
+
description: string
|
|
224
|
+
stories:
|
|
225
|
+
- id: string # STORY-001
|
|
226
|
+
name: string # "OAuth2 Social Login Flow"
|
|
227
|
+
interaction_boundary:
|
|
228
|
+
service: string
|
|
229
|
+
api_endpoint: string
|
|
230
|
+
method: string
|
|
231
|
+
request_contract: object
|
|
232
|
+
response_contract: object
|
|
233
|
+
error_states: [integer]
|
|
234
|
+
technical_acceptance: [string]
|
|
235
|
+
tasks:
|
|
236
|
+
- id: string # TASK-001
|
|
237
|
+
description: string
|
|
238
|
+
type: test | implementation | infrastructure | migration
|
|
239
|
+
linked_to:
|
|
240
|
+
type: service | entity | infrastructure
|
|
241
|
+
name: string
|
|
242
|
+
status: not_started | in_progress | complete | blocked
|
|
243
|
+
test_coverage:
|
|
244
|
+
test_file: string
|
|
245
|
+
standard_flows: boolean
|
|
246
|
+
error_states: boolean
|
|
247
|
+
edge_cases: boolean
|
|
248
|
+
|
|
249
|
+
test_suite_status:
|
|
250
|
+
total_stories: integer
|
|
251
|
+
tested_stories: integer
|
|
252
|
+
coverage_percentage: number
|
|
253
|
+
last_test_run: timestamp
|
|
254
|
+
|
|
255
|
+
# Example SDM
|
|
256
|
+
example:
|
|
257
|
+
metadata:
|
|
258
|
+
project_name: "example-saas"
|
|
259
|
+
version: "1.0.0"
|
|
260
|
+
last_updated: "2024-03-27T10:00:00Z"
|
|
261
|
+
architecture_type: "microservices"
|
|
262
|
+
|
|
263
|
+
tech_stack:
|
|
264
|
+
languages: ["Go", "TypeScript"]
|
|
265
|
+
frameworks: ["Echo", "React"]
|
|
266
|
+
databases: ["PostgreSQL", "Redis"]
|
|
267
|
+
infrastructure: ["Docker", "Kubernetes"]
|
|
268
|
+
|
|
269
|
+
user_types:
|
|
270
|
+
- role: "admin"
|
|
271
|
+
permissions: ["read:*", "write:*", "delete:*"]
|
|
272
|
+
authentication: "jwt"
|
|
273
|
+
- role: "user"
|
|
274
|
+
permissions: ["read:own", "write:own"]
|
|
275
|
+
authentication: "jwt"
|
|
276
|
+
|
|
277
|
+
entities:
|
|
278
|
+
- name: "User"
|
|
279
|
+
attributes:
|
|
280
|
+
- name: "id"
|
|
281
|
+
type: "uuid"
|
|
282
|
+
constraints: ["primary_key"]
|
|
283
|
+
- name: "email"
|
|
284
|
+
type: "varchar"
|
|
285
|
+
constraints: ["unique", "not_null"]
|
|
286
|
+
relationships:
|
|
287
|
+
- type: "one_to_many"
|
|
288
|
+
target: "Post"
|
|
289
|
+
foreign_key: "user_id"
|
|
290
|
+
|
|
291
|
+
services:
|
|
292
|
+
- name: "auth-service"
|
|
293
|
+
scope: "JWT authentication and session management"
|
|
294
|
+
tech_stack:
|
|
295
|
+
language: "Go"
|
|
296
|
+
framework: "Echo"
|
|
297
|
+
database: "PostgreSQL"
|
|
298
|
+
api:
|
|
299
|
+
type: "rest"
|
|
300
|
+
base_path: "/api/v1/auth"
|
|
301
|
+
port: 8080
|
|
302
|
+
data_access: ["User"]
|
|
303
|
+
|
|
304
|
+
communication:
|
|
305
|
+
- from: "web-frontend"
|
|
306
|
+
to: "auth-service"
|
|
307
|
+
protocol: "http"
|
|
308
|
+
pattern: "sync"
|
|
309
|
+
|
|
310
|
+
infrastructure:
|
|
311
|
+
deployment_target: "kubernetes"
|
|
312
|
+
components:
|
|
313
|
+
- type: "load_balancer"
|
|
314
|
+
name: "nginx-ingress"
|
|
315
|
+
technology: "nginx"
|
|
316
|
+
- type: "cache"
|
|
317
|
+
name: "redis-cache"
|
|
318
|
+
technology: "redis"
|
|
319
|
+
|
|
320
|
+
build_config:
|
|
321
|
+
- service: "auth-service"
|
|
322
|
+
build_tool: "make"
|
|
323
|
+
dockerfile: true
|
|
324
|
+
ci_cd: "github_actions"
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Example Design Module
|
|
2
|
+
|
|
3
|
+
A sample module demonstrating how to create design modules in Dhurandhar.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This module showcases:
|
|
8
|
+
|
|
9
|
+
- **Component Definition**: How to define system components (applications, services, datastores)
|
|
10
|
+
- **Relationships**: How to express dependencies between components
|
|
11
|
+
- **Build Processes**: How to define setup, development, and deployment workflows
|
|
12
|
+
- **Validation**: How to enforce design constraints and rules
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
This example implements a three-tier web application:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
┌─────────────────┐
|
|
20
|
+
│ Web Frontend │ (React + TypeScript)
|
|
21
|
+
│ Port: 3000 │
|
|
22
|
+
└────────┬────────┘
|
|
23
|
+
│ HTTP
|
|
24
|
+
▼
|
|
25
|
+
┌─────────────────┐
|
|
26
|
+
│ API Service │ (Node.js + TypeScript)
|
|
27
|
+
│ Port: 8080 │
|
|
28
|
+
└────────┬────────┘
|
|
29
|
+
│ SQL
|
|
30
|
+
▼
|
|
31
|
+
┌─────────────────┐
|
|
32
|
+
│ PostgreSQL │
|
|
33
|
+
│ Version: 15 │
|
|
34
|
+
└─────────────────┘
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Components
|
|
38
|
+
|
|
39
|
+
### Web Frontend
|
|
40
|
+
- **Type**: Application
|
|
41
|
+
- **Framework**: React
|
|
42
|
+
- **Language**: TypeScript
|
|
43
|
+
- **Port**: 3000
|
|
44
|
+
|
|
45
|
+
### API Service
|
|
46
|
+
- **Type**: Service
|
|
47
|
+
- **Framework**: Node.js
|
|
48
|
+
- **Language**: TypeScript
|
|
49
|
+
- **Port**: 8080
|
|
50
|
+
|
|
51
|
+
### Database
|
|
52
|
+
- **Type**: Datastore
|
|
53
|
+
- **Engine**: PostgreSQL
|
|
54
|
+
- **Version**: 15
|
|
55
|
+
|
|
56
|
+
## Build Processes
|
|
57
|
+
|
|
58
|
+
### Setup
|
|
59
|
+
Initial project setup including:
|
|
60
|
+
1. Install dependencies
|
|
61
|
+
2. Configure environment
|
|
62
|
+
3. Initialize database
|
|
63
|
+
|
|
64
|
+
### Development
|
|
65
|
+
Local development workflow:
|
|
66
|
+
1. Start database container
|
|
67
|
+
2. Run API in dev mode
|
|
68
|
+
3. Run frontend in dev mode
|
|
69
|
+
|
|
70
|
+
### Production
|
|
71
|
+
Production deployment:
|
|
72
|
+
1. Build frontend assets
|
|
73
|
+
2. Build API container
|
|
74
|
+
3. Deploy database migrations
|
|
75
|
+
4. Deploy containers
|
|
76
|
+
|
|
77
|
+
## Usage
|
|
78
|
+
|
|
79
|
+
Install this module:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
dhurandhar module --add example
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
View module information:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
dhurandhar module --info example
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Customization
|
|
92
|
+
|
|
93
|
+
You can use this module as a template for your own designs:
|
|
94
|
+
|
|
95
|
+
1. Copy the module structure
|
|
96
|
+
2. Modify `module.yaml` with your components
|
|
97
|
+
3. Define your relationships
|
|
98
|
+
4. Specify your build processes
|
|
99
|
+
5. Add validation rules
|
|
100
|
+
|
|
101
|
+
## Configuration
|
|
102
|
+
|
|
103
|
+
Configure the example module in `.dhurandhar/config.yaml`:
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
modules:
|
|
107
|
+
example:
|
|
108
|
+
example_setting: "my_value"
|
|
109
|
+
enable_feature: true
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Validation Rules
|
|
113
|
+
|
|
114
|
+
This module enforces:
|
|
115
|
+
|
|
116
|
+
- Required components must exist
|
|
117
|
+
- Only allowed relationship types between component types
|
|
118
|
+
- Component type constraints
|
|
119
|
+
|
|
120
|
+
## Dependencies
|
|
121
|
+
|
|
122
|
+
- **core**: Dhurandhar Core Module (required)
|
|
123
|
+
|
|
124
|
+
## Version
|
|
125
|
+
|
|
126
|
+
0.1.0
|
|
127
|
+
|
|
128
|
+
## License
|
|
129
|
+
|
|
130
|
+
MIT
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
code: example
|
|
2
|
+
name: "Example SaaS Platform - Engineering Blueprint"
|
|
3
|
+
version: "2.0.0"
|
|
4
|
+
description: "Technical blueprint for a multi-tenant SaaS platform with microservices"
|
|
5
|
+
|
|
6
|
+
# Module metadata
|
|
7
|
+
author: "Dhurandhar Project"
|
|
8
|
+
license: "MIT"
|
|
9
|
+
tags:
|
|
10
|
+
- saas
|
|
11
|
+
- microservices
|
|
12
|
+
- example
|
|
13
|
+
|
|
14
|
+
# Dependencies
|
|
15
|
+
dependencies:
|
|
16
|
+
- core
|
|
17
|
+
|
|
18
|
+
# Tech Stack
|
|
19
|
+
tech_stack:
|
|
20
|
+
primary_language: "Go"
|
|
21
|
+
frameworks: ["Echo", "GORM"]
|
|
22
|
+
databases: ["PostgreSQL", "Redis"]
|
|
23
|
+
infrastructure: ["Docker", "Kubernetes", "Nginx"]
|
|
24
|
+
|
|
25
|
+
# User Types - Technical definition
|
|
26
|
+
user_types:
|
|
27
|
+
- role: "admin"
|
|
28
|
+
permissions: ["read:*", "write:*", "delete:*"]
|
|
29
|
+
authentication: "jwt"
|
|
30
|
+
attributes:
|
|
31
|
+
is_superuser: true
|
|
32
|
+
|
|
33
|
+
- role: "tenant_admin"
|
|
34
|
+
permissions: ["read:tenant", "write:tenant", "manage:users"]
|
|
35
|
+
authentication: "jwt"
|
|
36
|
+
attributes:
|
|
37
|
+
tenant_id: "required"
|
|
38
|
+
|
|
39
|
+
- role: "user"
|
|
40
|
+
permissions: ["read:own", "write:own"]
|
|
41
|
+
authentication: "jwt"
|
|
42
|
+
attributes:
|
|
43
|
+
tenant_id: "required"
|
|
44
|
+
|
|
45
|
+
- role: "api_client"
|
|
46
|
+
permissions: ["read:api", "write:api"]
|
|
47
|
+
authentication: "api_key"
|
|
48
|
+
|
|
49
|
+
# Entities - ERD-like data model
|
|
50
|
+
entities:
|
|
51
|
+
- name: "Tenant"
|
|
52
|
+
table_name: "tenants"
|
|
53
|
+
attributes:
|
|
54
|
+
- name: "id"
|
|
55
|
+
type: "uuid"
|
|
56
|
+
constraints: ["primary_key"]
|
|
57
|
+
- name: "name"
|
|
58
|
+
type: "varchar"
|
|
59
|
+
constraints: ["not_null", "unique"]
|
|
60
|
+
- name: "subdomain"
|
|
61
|
+
type: "varchar"
|
|
62
|
+
constraints: ["not_null", "unique", "indexed"]
|
|
63
|
+
- name: "plan"
|
|
64
|
+
type: "varchar"
|
|
65
|
+
constraints: ["not_null"]
|
|
66
|
+
- name: "status"
|
|
67
|
+
type: "varchar"
|
|
68
|
+
constraints: ["not_null"]
|
|
69
|
+
- name: "created_at"
|
|
70
|
+
type: "timestamp"
|
|
71
|
+
constraints: ["not_null"]
|
|
72
|
+
relationships:
|
|
73
|
+
- type: "one_to_many"
|
|
74
|
+
target: "User"
|
|
75
|
+
foreign_key: "tenant_id"
|
|
76
|
+
|
|
77
|
+
- name: "User"
|
|
78
|
+
table_name: "users"
|
|
79
|
+
attributes:
|
|
80
|
+
- name: "id"
|
|
81
|
+
type: "uuid"
|
|
82
|
+
constraints: ["primary_key"]
|
|
83
|
+
- name: "tenant_id"
|
|
84
|
+
type: "uuid"
|
|
85
|
+
constraints: ["not_null", "indexed"]
|
|
86
|
+
- name: "email"
|
|
87
|
+
type: "varchar"
|
|
88
|
+
constraints: ["not_null", "unique"]
|
|
89
|
+
- name: "password_hash"
|
|
90
|
+
type: "varchar"
|
|
91
|
+
constraints: ["not_null"]
|
|
92
|
+
- name: "role"
|
|
93
|
+
type: "varchar"
|
|
94
|
+
constraints: ["not_null"]
|
|
95
|
+
- name: "created_at"
|
|
96
|
+
type: "timestamp"
|
|
97
|
+
constraints: ["not_null"]
|
|
98
|
+
relationships:
|
|
99
|
+
- type: "many_to_one"
|
|
100
|
+
target: "Tenant"
|
|
101
|
+
foreign_key: "tenant_id"
|
|
102
|
+
- type: "one_to_many"
|
|
103
|
+
target: "Session"
|
|
104
|
+
foreign_key: "user_id"
|
|
105
|
+
|
|
106
|
+
- name: "Session"
|
|
107
|
+
table_name: "sessions"
|
|
108
|
+
attributes:
|
|
109
|
+
- name: "id"
|
|
110
|
+
type: "uuid"
|
|
111
|
+
constraints: ["primary_key"]
|
|
112
|
+
- name: "user_id"
|
|
113
|
+
type: "uuid"
|
|
114
|
+
constraints: ["not_null", "indexed"]
|
|
115
|
+
- name: "token"
|
|
116
|
+
type: "varchar"
|
|
117
|
+
constraints: ["not_null", "unique"]
|
|
118
|
+
- name: "expires_at"
|
|
119
|
+
type: "timestamp"
|
|
120
|
+
constraints: ["not_null"]
|
|
121
|
+
- name: "created_at"
|
|
122
|
+
type: "timestamp"
|
|
123
|
+
constraints: ["not_null"]
|
|
124
|
+
relationships:
|
|
125
|
+
- type: "many_to_one"
|
|
126
|
+
target: "User"
|
|
127
|
+
foreign_key: "user_id"
|
|
128
|
+
|
|
129
|
+
# Services - Microservices with tech stack
|
|
130
|
+
services:
|
|
131
|
+
- name: "auth-service"
|
|
132
|
+
scope: "JWT authentication, session management, and tenant isolation"
|
|
133
|
+
tech_stack:
|
|
134
|
+
language: "Go"
|
|
135
|
+
framework: "Echo"
|
|
136
|
+
database: "PostgreSQL"
|
|
137
|
+
orm: "GORM"
|
|
138
|
+
api:
|
|
139
|
+
type: "rest"
|
|
140
|
+
base_path: "/api/v1/auth"
|
|
141
|
+
port: 8080
|
|
142
|
+
endpoints:
|
|
143
|
+
- method: "POST"
|
|
144
|
+
path: "/login"
|
|
145
|
+
description: "Authenticate user, return JWT"
|
|
146
|
+
- method: "POST"
|
|
147
|
+
path: "/logout"
|
|
148
|
+
description: "Invalidate session"
|
|
149
|
+
- method: "POST"
|
|
150
|
+
path: "/refresh"
|
|
151
|
+
description: "Refresh JWT token"
|
|
152
|
+
dependencies: []
|
|
153
|
+
data_access: ["User", "Session", "Tenant"]
|
|
154
|
+
environment:
|
|
155
|
+
required: ["DATABASE_URL", "JWT_SECRET", "JWT_EXPIRY"]
|
|
156
|
+
|
|
157
|
+
- name: "tenant-service"
|
|
158
|
+
scope: "Multi-tenant management, provisioning, and billing"
|
|
159
|
+
tech_stack:
|
|
160
|
+
language: "Go"
|
|
161
|
+
framework: "Echo"
|
|
162
|
+
database: "PostgreSQL"
|
|
163
|
+
orm: "GORM"
|
|
164
|
+
api:
|
|
165
|
+
type: "rest"
|
|
166
|
+
base_path: "/api/v1/tenants"
|
|
167
|
+
port: 8081
|
|
168
|
+
dependencies: ["auth-service"]
|
|
169
|
+
data_access: ["Tenant", "User"]
|
|
170
|
+
environment:
|
|
171
|
+
required: ["DATABASE_URL"]
|
|
172
|
+
|
|
173
|
+
- name: "user-service"
|
|
174
|
+
scope: "User CRUD, profile management, role assignment"
|
|
175
|
+
tech_stack:
|
|
176
|
+
language: "Go"
|
|
177
|
+
framework: "Echo"
|
|
178
|
+
database: "PostgreSQL"
|
|
179
|
+
orm: "GORM"
|
|
180
|
+
api:
|
|
181
|
+
type: "rest"
|
|
182
|
+
base_path: "/api/v1/users"
|
|
183
|
+
port: 8082
|
|
184
|
+
dependencies: ["auth-service"]
|
|
185
|
+
data_access: ["User", "Tenant"]
|
|
186
|
+
environment:
|
|
187
|
+
required: ["DATABASE_URL"]
|
|
188
|
+
|
|
189
|
+
# Service Communication
|
|
190
|
+
communication:
|
|
191
|
+
- from: "tenant-service"
|
|
192
|
+
to: "auth-service"
|
|
193
|
+
protocol: "http"
|
|
194
|
+
pattern: "sync"
|
|
195
|
+
- from: "user-service"
|
|
196
|
+
to: "auth-service"
|
|
197
|
+
protocol: "http"
|
|
198
|
+
pattern: "sync"
|
|
199
|
+
|
|
200
|
+
# Infrastructure
|
|
201
|
+
infrastructure:
|
|
202
|
+
deployment_target: "kubernetes"
|
|
203
|
+
components:
|
|
204
|
+
- type: "load_balancer"
|
|
205
|
+
name: "nginx-ingress"
|
|
206
|
+
technology: "nginx"
|
|
207
|
+
- type: "cache"
|
|
208
|
+
name: "redis-cache"
|
|
209
|
+
technology: "redis"
|
|
210
|
+
- type: "database"
|
|
211
|
+
name: "postgres-cluster"
|
|
212
|
+
technology: "postgresql"
|
|
213
|
+
|
|
214
|
+
# Build Configuration
|
|
215
|
+
build_config:
|
|
216
|
+
- service: "auth-service"
|
|
217
|
+
build_tool: "make"
|
|
218
|
+
dockerfile: true
|
|
219
|
+
ci_cd: "github_actions"
|
|
220
|
+
|
|
221
|
+
- service: "tenant-service"
|
|
222
|
+
build_tool: "make"
|
|
223
|
+
dockerfile: true
|
|
224
|
+
ci_cd: "github_actions"
|
|
225
|
+
|
|
226
|
+
- service: "user-service"
|
|
227
|
+
build_tool: "make"
|
|
228
|
+
dockerfile: true
|
|
229
|
+
ci_cd: "github_actions"
|
|
230
|
+
|
|
231
|
+
# Build process definitions (simplified)
|
|
232
|
+
build_processes:
|
|
233
|
+
- name: "setup"
|
|
234
|
+
description: "Local development setup"
|
|
235
|
+
steps:
|
|
236
|
+
- "make deps"
|
|
237
|
+
- "docker-compose up -d postgres redis"
|
|
238
|
+
- "make migrate"
|
|
239
|
+
|
|
240
|
+
- name: "development"
|
|
241
|
+
description: "Start all services"
|
|
242
|
+
steps:
|
|
243
|
+
- "make run-auth"
|
|
244
|
+
- "make run-tenant"
|
|
245
|
+
- "make run-user"
|
|
246
|
+
|
|
247
|
+
- name: "production"
|
|
248
|
+
description: "Deploy to Kubernetes"
|
|
249
|
+
steps:
|
|
250
|
+
- "make build-all"
|
|
251
|
+
- "kubectl apply -f k8s/"
|
|
252
|
+
- "make migrate-prod"
|