new changes
This commit is contained in:
64
architecture/2026/01-bounded-contexts.md
Normal file
64
architecture/2026/01-bounded-contexts.md
Normal file
@@ -0,0 +1,64 @@
|
||||
# YakPanel 2026 Bounded Contexts and Ownership
|
||||
|
||||
This document defines ownership boundaries between the Laravel control plane and Go execution services.
|
||||
|
||||
## Domain Contexts
|
||||
|
||||
### IdentityAndAccess (Laravel)
|
||||
- Owns tenants, users, membership, roles, permissions, and scoped policy evaluation.
|
||||
- Exposes authn/authz services to all modules.
|
||||
- Guarantees tenant isolation at query and policy layers.
|
||||
|
||||
### TenantBillingAndLifecycle (Laravel)
|
||||
- Owns tenant lifecycle, plan limits, billing integration hooks, and quota enforcement.
|
||||
- Emits events used by job orchestration and plugin entitlements.
|
||||
|
||||
### InventoryAndServerRegistry (Laravel + agent-gateway)
|
||||
- Laravel owns canonical server records, labels, region mapping, and assignment.
|
||||
- `agent-gateway` owns live session presence and online/offline detection.
|
||||
|
||||
### HostingResourceManagement (Laravel)
|
||||
- Owns site, domain, SSL metadata, FTP metadata, database metadata, and lifecycle workflows.
|
||||
- Delegates mutable node operations to Go engines through command orchestration.
|
||||
|
||||
### WorkloadOrchestration (Laravel + Go engines)
|
||||
- Laravel owns workflow composition, step state machine, retry policy, audit trail.
|
||||
- Go services own command execution logic for privileged operations.
|
||||
|
||||
### PluginMarketplace (Laravel + Go engine-fileops/engine-docker)
|
||||
- Laravel owns catalog, signatures, compatibility metadata, entitlements.
|
||||
- Go services own installation actions on managed nodes.
|
||||
|
||||
### ObservabilityAndAlerting (Laravel + metrics pipeline)
|
||||
- Laravel owns dashboards, alert rules, routing, and incident metadata.
|
||||
- Metrics ingestion pipeline owns aggregation and retention.
|
||||
|
||||
### IntegrationAPI (Laravel)
|
||||
- Owns third-party API tokens, webhooks, and scoped public endpoints.
|
||||
|
||||
## Service Ownership Matrix
|
||||
|
||||
| Capability | Laravel Module | Go Service | Notes |
|
||||
|---|---|---|---|
|
||||
| Tenant and RBAC | Auth, Tenant, Rbac | N/A | Policy checks happen before dispatch. |
|
||||
| Server enrollment metadata | Server | agent-gateway | Enrollment token issued by Laravel, redeemed via gateway. |
|
||||
| Website lifecycle | Site, Domain, Ssl | engine-site | Laravel stores desired state; engine enforces actual state. |
|
||||
| Docker app deployment | Apps | engine-docker | Templates validated in Laravel, executed by engine-docker. |
|
||||
| MySQL/Redis management | Database, Redis | engine-db | Credentials references stored in Laravel. |
|
||||
| File operations | Files | engine-fileops | Strict allowlists and safe path constraints. |
|
||||
| Firewall/security | Firewall | engine-security | Security engine returns audit evidence artifacts. |
|
||||
| Backup and restore | Backups | engine-backup | Backup plans defined in Laravel. |
|
||||
| Agent session routing | Agents | agent-gateway | mTLS and command channel handling in gateway. |
|
||||
| Monitoring and alerts | Metrics, Alerts | metrics-ingest | Live streams + retained aggregates. |
|
||||
|
||||
## Cross-Context Contracts
|
||||
|
||||
- Commands are immutable envelopes with `idempotency_key`.
|
||||
- All control-plane writes emit domain events.
|
||||
- Engines are stateless workers and read policy-free command payloads.
|
||||
- Agents execute only capability-approved command types.
|
||||
|
||||
## Non-Goals
|
||||
|
||||
- No direct shell command execution from Laravel workers.
|
||||
- No shared mutable state between engine services outside contract stores/queues.
|
||||
184
architecture/2026/02-core-schema.sql
Normal file
184
architecture/2026/02-core-schema.sql
Normal file
@@ -0,0 +1,184 @@
|
||||
-- YakPanel 2026 core schema
|
||||
-- PostgreSQL 15+ compatible
|
||||
|
||||
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
||||
CREATE EXTENSION IF NOT EXISTS "citext";
|
||||
|
||||
-- Shared timestamps helper convention:
|
||||
-- created_at timestamptz not null default now()
|
||||
-- updated_at timestamptz not null default now()
|
||||
|
||||
CREATE TABLE tenants (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
name varchar(150) NOT NULL,
|
||||
slug citext NOT NULL UNIQUE,
|
||||
status varchar(32) NOT NULL DEFAULT 'active',
|
||||
plan_code varchar(64) NOT NULL DEFAULT 'starter',
|
||||
settings jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE users (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
email citext NOT NULL UNIQUE,
|
||||
password_hash text NOT NULL,
|
||||
display_name varchar(120) NOT NULL,
|
||||
is_platform_admin boolean NOT NULL DEFAULT false,
|
||||
last_login_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE tenant_users (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
status varchar(32) NOT NULL DEFAULT 'active',
|
||||
joined_at timestamptz NOT NULL DEFAULT now(),
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE roles (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
name varchar(64) NOT NULL,
|
||||
description text NOT NULL DEFAULT '',
|
||||
is_system boolean NOT NULL DEFAULT false,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE permissions (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
code varchar(100) NOT NULL UNIQUE,
|
||||
description text NOT NULL DEFAULT '',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE role_permissions (
|
||||
role_id uuid NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
permission_id uuid NOT NULL REFERENCES permissions(id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (role_id, permission_id)
|
||||
);
|
||||
|
||||
CREATE TABLE user_roles (
|
||||
tenant_user_id uuid NOT NULL REFERENCES tenant_users(id) ON DELETE CASCADE,
|
||||
role_id uuid NOT NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (tenant_user_id, role_id)
|
||||
);
|
||||
|
||||
CREATE TABLE scopes (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
role_id uuid NULL REFERENCES roles(id) ON DELETE CASCADE,
|
||||
resource_type varchar(64) NOT NULL,
|
||||
resource_id uuid NULL,
|
||||
action varchar(64) NOT NULL,
|
||||
effect varchar(8) NOT NULL DEFAULT 'allow',
|
||||
conditions jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE servers (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
name varchar(120) NOT NULL,
|
||||
host varchar(255) NOT NULL,
|
||||
port integer NOT NULL DEFAULT 443,
|
||||
os_type varchar(32) NOT NULL,
|
||||
status varchar(32) NOT NULL DEFAULT 'provisioning',
|
||||
region varchar(64) NOT NULL DEFAULT 'global',
|
||||
labels jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
heartbeat_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, name)
|
||||
);
|
||||
|
||||
CREATE TABLE server_agents (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
server_id uuid NOT NULL REFERENCES servers(id) ON DELETE CASCADE,
|
||||
agent_uid varchar(128) NOT NULL UNIQUE,
|
||||
agent_version varchar(32) NOT NULL,
|
||||
capabilities jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
cert_fingerprint varchar(255) NOT NULL,
|
||||
last_seen_at timestamptz NULL,
|
||||
status varchar(32) NOT NULL DEFAULT 'offline',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE jobs (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
server_id uuid NULL REFERENCES servers(id) ON DELETE SET NULL,
|
||||
requested_by_user_id uuid NULL REFERENCES users(id) ON DELETE SET NULL,
|
||||
type varchar(64) NOT NULL,
|
||||
status varchar(32) NOT NULL DEFAULT 'queued',
|
||||
priority smallint NOT NULL DEFAULT 5,
|
||||
idempotency_key varchar(120) NOT NULL,
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
result jsonb NULL,
|
||||
started_at timestamptz NULL,
|
||||
finished_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, idempotency_key)
|
||||
);
|
||||
|
||||
CREATE TABLE job_steps (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
job_id uuid NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
||||
step_order integer NOT NULL,
|
||||
name varchar(80) NOT NULL,
|
||||
status varchar(32) NOT NULL DEFAULT 'pending',
|
||||
input jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
output jsonb NULL,
|
||||
error text NULL,
|
||||
started_at timestamptz NULL,
|
||||
finished_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (job_id, step_order)
|
||||
);
|
||||
|
||||
CREATE TABLE job_events (
|
||||
id bigserial PRIMARY KEY,
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
job_id uuid NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
||||
event_type varchar(64) NOT NULL,
|
||||
source varchar(32) NOT NULL,
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_job_events_tenant_job_created ON job_events (tenant_id, job_id, created_at DESC);
|
||||
|
||||
CREATE TABLE audit_logs (
|
||||
id bigserial PRIMARY KEY,
|
||||
tenant_id uuid NULL REFERENCES tenants(id) ON DELETE SET NULL,
|
||||
actor_user_id uuid NULL REFERENCES users(id) ON DELETE SET NULL,
|
||||
actor_type varchar(32) NOT NULL,
|
||||
action varchar(80) NOT NULL,
|
||||
resource_type varchar(64) NOT NULL,
|
||||
resource_id uuid NULL,
|
||||
request_id varchar(64) NULL,
|
||||
ip inet NULL,
|
||||
user_agent text NULL,
|
||||
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX idx_audit_logs_tenant_created ON audit_logs (tenant_id, created_at DESC);
|
||||
CREATE INDEX idx_scopes_tenant_action ON scopes (tenant_id, action);
|
||||
CREATE INDEX idx_servers_tenant_status ON servers (tenant_id, status);
|
||||
CREATE INDEX idx_jobs_tenant_status ON jobs (tenant_id, status);
|
||||
123
architecture/2026/03-agent-protocol-v1.md
Normal file
123
architecture/2026/03-agent-protocol-v1.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# YakPanel Agent Protocol v1
|
||||
|
||||
## Goals
|
||||
- Secure control channel between panel and managed servers.
|
||||
- Reliable command execution with resumable progress.
|
||||
- Capability-aware execution and strict auditability.
|
||||
|
||||
## Transport and Session
|
||||
- Primary transport: bidirectional gRPC stream over mTLS.
|
||||
- Fallback transport: WebSocket over mTLS.
|
||||
- Agent uses outbound connection only.
|
||||
- Server requires certificate pinning and protocol version negotiation.
|
||||
|
||||
## Version Negotiation
|
||||
- Agent sends `protocol_versions` during hello.
|
||||
- Gateway picks highest compatible version and responds with `selected_version`.
|
||||
- If no compatible version exists, gateway returns `ERR_UNSUPPORTED_VERSION`.
|
||||
|
||||
## Message Envelope (common fields)
|
||||
- `message_id` (uuid): unique per message.
|
||||
- `timestamp` (RFC3339 UTC): replay protection.
|
||||
- `tenant_id` (uuid): owning tenant.
|
||||
- `server_id` (uuid): managed server.
|
||||
- `agent_id` (string): persistent agent identity.
|
||||
- `trace_id` (string): distributed trace correlation.
|
||||
- `signature` (base64): detached signature over canonical payload.
|
||||
|
||||
## Enrollment Flow
|
||||
1. Agent starts with one-time bootstrap token.
|
||||
2. Agent calls `EnrollRequest` with host fingerprint and capabilities.
|
||||
3. Gateway validates token and issues short-lived enrollment certificate.
|
||||
4. Agent re-connects with cert; gateway persists `agent_id` and fingerprints.
|
||||
5. Enrollment token is revoked after successful bind.
|
||||
|
||||
## Heartbeat Flow
|
||||
- Interval: every 10 seconds.
|
||||
- Payload includes:
|
||||
- `agent_version`
|
||||
- `capability_hash`
|
||||
- `system_load` (cpu, mem, disk)
|
||||
- `service_states` (nginx/apache/ols/mysql/redis/docker)
|
||||
- Gateway updates presence and emits server status event.
|
||||
- Missing 3 consecutive heartbeats marks agent as degraded; 6 marks offline.
|
||||
|
||||
## Command Flow
|
||||
|
||||
### CommandRequest
|
||||
- `cmd_id` (uuid)
|
||||
- `job_id` (uuid)
|
||||
- `type` (enum): `SITE_CREATE`, `SITE_DELETE`, `SSL_ISSUE`, `SSL_APPLY`, `SERVICE_RELOAD`, `DOCKER_DEPLOY`, etc.
|
||||
- `args` (json map)
|
||||
- `timeout_sec` (int)
|
||||
- `idempotency_key` (string)
|
||||
- `required_capabilities` (string array)
|
||||
|
||||
### Agent behavior
|
||||
- Validate signature and timestamp window.
|
||||
- Validate required capability set.
|
||||
- Return ACK immediately with acceptance or reject reason.
|
||||
- Emit progress events at step boundaries.
|
||||
- Emit final result with exit code, summaries, and artifact references.
|
||||
|
||||
### Retry and Exactly-once strategy
|
||||
- Gateway retries only if no terminal result and timeout exceeded.
|
||||
- Agent deduplicates by `idempotency_key` and returns last known terminal state for duplicates.
|
||||
- Workflow layer (Laravel) provides exactly-once user-visible semantics.
|
||||
|
||||
## Event Types
|
||||
- `AGENT_HELLO`
|
||||
- `AGENT_HEARTBEAT`
|
||||
- `COMMAND_ACK`
|
||||
- `COMMAND_PROGRESS`
|
||||
- `COMMAND_LOG`
|
||||
- `COMMAND_RESULT`
|
||||
- `COMMAND_ERROR`
|
||||
- `AGENT_STATE_CHANGED`
|
||||
|
||||
## Error Model
|
||||
- Error codes:
|
||||
- `ERR_UNAUTHORIZED`
|
||||
- `ERR_UNSUPPORTED_VERSION`
|
||||
- `ERR_INVALID_SIGNATURE`
|
||||
- `ERR_REPLAY_DETECTED`
|
||||
- `ERR_CAPABILITY_MISSING`
|
||||
- `ERR_INVALID_ARGS`
|
||||
- `ERR_EXECUTION_FAILED`
|
||||
- `ERR_TIMEOUT`
|
||||
- Every error includes `code`, `message`, `retryable`, `details`.
|
||||
|
||||
## Security Controls
|
||||
- mTLS with rotating short-lived certs.
|
||||
- Nonce + timestamp replay protection.
|
||||
- Detached command signatures from panel signing key.
|
||||
- Agent command allowlist by capability.
|
||||
- Immutable append-only event log in control plane.
|
||||
|
||||
## Minimal Protobuf Sketch
|
||||
|
||||
```proto
|
||||
syntax = "proto3";
|
||||
package yakpanel.agent.v1;
|
||||
|
||||
message Envelope {
|
||||
string message_id = 1;
|
||||
string timestamp = 2;
|
||||
string tenant_id = 3;
|
||||
string server_id = 4;
|
||||
string agent_id = 5;
|
||||
string trace_id = 6;
|
||||
bytes signature = 7;
|
||||
}
|
||||
|
||||
message CommandRequest {
|
||||
Envelope envelope = 1;
|
||||
string cmd_id = 2;
|
||||
string job_id = 3;
|
||||
string type = 4;
|
||||
string args_json = 5;
|
||||
int32 timeout_sec = 6;
|
||||
string idempotency_key = 7;
|
||||
repeated string required_capabilities = 8;
|
||||
}
|
||||
```
|
||||
22
architecture/2026/04-server-plane-implementation.md
Normal file
22
architecture/2026/04-server-plane-implementation.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Server Plane Implementation (v1)
|
||||
|
||||
## Implemented Components
|
||||
- Laravel server registry routes and controllers under `panel-api`.
|
||||
- Agent enrollment/capability/session endpoints in `panel-api`.
|
||||
- Go command contract and dispatcher interface in `control-plane-go`.
|
||||
- `agent-gateway` process entrypoint for session and heartbeat responsibilities.
|
||||
|
||||
## End-to-End Control Flow
|
||||
1. User creates server via `POST /api/v1/servers`.
|
||||
2. User requests one-time enrollment token.
|
||||
3. Agent enrolls with gateway, obtains persistent identity.
|
||||
4. Laravel writes job and dispatches command envelope.
|
||||
5. Go dispatcher publishes command to execution topic.
|
||||
6. Agent executes command and streams results back.
|
||||
7. Laravel updates job state and exposes real-time status to UI.
|
||||
|
||||
## Next Implementation Edges
|
||||
- Persist server/agent entities in Eloquent models.
|
||||
- Add request validation and RBAC middleware to server routes.
|
||||
- Implement Redis Streams/NATS queue adapter for dispatcher queue interface.
|
||||
- Add gateway gRPC service and heartbeat/session persistence adapter.
|
||||
26
architecture/2026/05-hosting-mvp.md
Normal file
26
architecture/2026/05-hosting-mvp.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Hosting MVP Implementation Notes
|
||||
|
||||
## Scope
|
||||
- Website create/update/delete workflows.
|
||||
- Domain binding/unbinding.
|
||||
- SSL issue/apply/renew automation.
|
||||
- Webserver adapter support: Nginx, Apache, OpenLiteSpeed.
|
||||
|
||||
## Control Plane APIs
|
||||
- `GET /api/v1/sites`
|
||||
- `POST /api/v1/sites`
|
||||
- `POST /api/v1/sites/{site}/domains`
|
||||
- `POST /api/v1/ssl/issue`
|
||||
- `POST /api/v1/ssl/apply`
|
||||
- `POST /api/v1/ssl/renew`
|
||||
|
||||
## Execution Contracts
|
||||
- `SITE_CREATE`, `SITE_UPDATE`, `SITE_DELETE`
|
||||
- `DOMAIN_ADD`, `DOMAIN_REMOVE`
|
||||
- `SSL_ISSUE`, `SSL_APPLY`, `SSL_RENEW`
|
||||
- `WEBSERVER_RELOAD`
|
||||
|
||||
## Runtime Guarantees
|
||||
- Every operation is a tracked job with progress updates.
|
||||
- SSL operations require DNS precheck and challenge validation before apply.
|
||||
- Webserver reload only occurs after adapter-specific config validation.
|
||||
115
architecture/2026/06-api-structure.yaml
Normal file
115
architecture/2026/06-api-structure.yaml
Normal file
@@ -0,0 +1,115 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: YakPanel Control Plane API
|
||||
version: 1.0.0
|
||||
servers:
|
||||
- url: /api/v1
|
||||
paths:
|
||||
/auth/login:
|
||||
post:
|
||||
tags: [Auth]
|
||||
summary: Authenticate user and return token
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
/tenants:
|
||||
get:
|
||||
tags: [Tenants]
|
||||
summary: List tenant memberships
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
/servers:
|
||||
get:
|
||||
tags: [Servers]
|
||||
summary: List managed servers
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
post:
|
||||
tags: [Servers]
|
||||
summary: Register server metadata
|
||||
responses:
|
||||
"202": { description: Accepted }
|
||||
/sites:
|
||||
get:
|
||||
tags: [Sites]
|
||||
summary: List sites
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
post:
|
||||
tags: [Sites]
|
||||
summary: Create site
|
||||
responses:
|
||||
"202": { description: Accepted }
|
||||
/ssl/issue:
|
||||
post:
|
||||
tags: [SSL]
|
||||
summary: Issue certificate
|
||||
responses:
|
||||
"202": { description: Accepted }
|
||||
/files/list:
|
||||
post:
|
||||
tags: [Files]
|
||||
summary: List files in allowed path scope
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
/cron/jobs:
|
||||
get:
|
||||
tags: [Cron]
|
||||
summary: List cron jobs
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
post:
|
||||
tags: [Cron]
|
||||
summary: Create cron job
|
||||
responses:
|
||||
"202": { description: Accepted }
|
||||
/firewall/rules:
|
||||
get:
|
||||
tags: [Firewall]
|
||||
summary: List firewall rules
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
post:
|
||||
tags: [Firewall]
|
||||
summary: Add firewall rule
|
||||
responses:
|
||||
"202": { description: Accepted }
|
||||
/backups/policies:
|
||||
get:
|
||||
tags: [Backups]
|
||||
summary: List backup policies
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
post:
|
||||
tags: [Backups]
|
||||
summary: Create backup policy
|
||||
responses:
|
||||
"201": { description: Created }
|
||||
/plugins/market:
|
||||
get:
|
||||
tags: [Marketplace]
|
||||
summary: Browse plugin marketplace
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
/plugins/install:
|
||||
post:
|
||||
tags: [Marketplace]
|
||||
summary: Install plugin
|
||||
responses:
|
||||
"202": { description: Accepted }
|
||||
/metrics/servers/{serverId}/live:
|
||||
get:
|
||||
tags: [Monitoring]
|
||||
summary: Get latest real-time server metrics
|
||||
parameters:
|
||||
- in: path
|
||||
name: serverId
|
||||
required: true
|
||||
schema: { type: string, format: uuid }
|
||||
responses:
|
||||
"200": { description: OK }
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
37
architecture/2026/07-microservices-breakdown.md
Normal file
37
architecture/2026/07-microservices-breakdown.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Go Microservices Breakdown
|
||||
|
||||
## Services
|
||||
|
||||
### agent-gateway
|
||||
- Terminates mTLS channels from agents.
|
||||
- Tracks sessions, heartbeats, and capability maps.
|
||||
- Relays command envelopes and result events.
|
||||
|
||||
### engine-site
|
||||
- Manages site config generation, domain bindings, and SSL apply pipelines.
|
||||
- Supports Nginx, Apache, OpenLiteSpeed provider adapters.
|
||||
|
||||
### engine-docker
|
||||
- Deploys one-click apps via compose templates.
|
||||
- Handles image pulls, health checks, and rollback.
|
||||
|
||||
### engine-db
|
||||
- Manages MySQL and Redis lifecycle commands.
|
||||
- Executes create database/user, backup, restore primitives.
|
||||
|
||||
### engine-security
|
||||
- Applies firewall policies and security hardening commands.
|
||||
- Integrates fail2ban and baseline checks.
|
||||
|
||||
### engine-backup
|
||||
- Runs backup plans and restore workflows.
|
||||
- Pushes artifacts to object storage providers.
|
||||
|
||||
### engine-fileops
|
||||
- Secure file manager operations with path policy controls.
|
||||
- Chunked upload, download token issuance, lock-aware editing.
|
||||
|
||||
## Communication Model
|
||||
- Inbound command envelopes from Laravel orchestrator.
|
||||
- Internal queue topic fan-out by command type.
|
||||
- Outbound event stream for progress, logs, and terminal results.
|
||||
58
architecture/2026/08-folder-structure.md
Normal file
58
architecture/2026/08-folder-structure.md
Normal file
@@ -0,0 +1,58 @@
|
||||
# Suggested 2026 Folder Structure
|
||||
|
||||
## Root Layout
|
||||
|
||||
```text
|
||||
YakPanel-master/
|
||||
panel-api/ # Laravel control plane
|
||||
panel-web/ # Next.js + Tailwind UI
|
||||
control-plane-go/ # Go execution services
|
||||
yak-agent/ # Go daemon on managed servers
|
||||
architecture/2026/ # Blueprint and contracts
|
||||
```
|
||||
|
||||
## Laravel (`panel-api`)
|
||||
- `app/Modules/Auth`
|
||||
- `app/Modules/Tenant`
|
||||
- `app/Modules/Rbac`
|
||||
- `app/Modules/Server`
|
||||
- `app/Modules/Agents`
|
||||
- `app/Modules/Site`
|
||||
- `app/Modules/Ssl`
|
||||
- `app/Modules/Files`
|
||||
- `app/Modules/Cron`
|
||||
- `app/Modules/Firewall`
|
||||
- `app/Modules/Backups`
|
||||
- `app/Modules/Plugin`
|
||||
- `app/Modules/Metrics`
|
||||
- `routes/api_v1`
|
||||
|
||||
## Next.js (`panel-web`)
|
||||
- `src/app/(dashboard)`
|
||||
- `src/features/server`
|
||||
- `src/features/sites`
|
||||
- `src/features/marketplace`
|
||||
- `src/features/metrics`
|
||||
- `src/lib/api`
|
||||
- `src/lib/ws`
|
||||
|
||||
## Go control-plane (`control-plane-go`)
|
||||
- `cmd/agent-gateway`
|
||||
- `cmd/engine-site`
|
||||
- `cmd/engine-docker`
|
||||
- `cmd/engine-db`
|
||||
- `cmd/engine-security`
|
||||
- `cmd/engine-backup`
|
||||
- `cmd/engine-fileops`
|
||||
- `internal/orchestration`
|
||||
- `internal/webserver`
|
||||
- `pkg/contracts`
|
||||
- `pkg/proto`
|
||||
|
||||
## Go agent (`yak-agent`)
|
||||
- `cmd/agent`
|
||||
- `internal/transport`
|
||||
- `internal/executor`
|
||||
- `internal/collectors`
|
||||
- `internal/updater`
|
||||
- `pkg/capabilities`
|
||||
30
architecture/2026/09-development-roadmap.md
Normal file
30
architecture/2026/09-development-roadmap.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# YakPanel 2026 Development Roadmap
|
||||
|
||||
## Phase 1: Foundation (Weeks 1-3)
|
||||
- Stand up repositories and CI pipelines.
|
||||
- Define coding standards, security checks, and observability baseline.
|
||||
- Establish Docker-based developer environment.
|
||||
|
||||
## Phase 2: Identity + Tenancy (Weeks 4-6)
|
||||
- Implement tenants, users, tenant membership, and RBAC scopes.
|
||||
- Add API tokens, session controls, and audit logging.
|
||||
|
||||
## Phase 3: Server Plane (Weeks 7-10)
|
||||
- Implement server registry, agent enrollment tokens, and live sessions.
|
||||
- Deliver command orchestration and event stream updates.
|
||||
|
||||
## Phase 4: Hosting MVP (Weeks 11-15)
|
||||
- Implement sites/domains/SSL workflows.
|
||||
- Add Nginx/Apache/OpenLiteSpeed adapters and validation gates.
|
||||
|
||||
## Phase 5: Platform Operations (Weeks 16-20)
|
||||
- Deliver file manager, cron manager, firewall, backup policy engine.
|
||||
- Add MySQL/Redis lifecycle management.
|
||||
|
||||
## Phase 6: Marketplace + Monitoring (Weeks 21-25)
|
||||
- Deliver plugin marketplace catalog and signed install pipeline.
|
||||
- Build real-time metrics dashboard and alerting engine.
|
||||
|
||||
## Phase 7: SaaS Hardening (Weeks 26-30)
|
||||
- Quotas, plan enforcement, webhook integrations, public API.
|
||||
- Multi-region readiness and disaster recovery rehearsals.
|
||||
41
architecture/2026/10-ops-marketplace-observability.md
Normal file
41
architecture/2026/10-ops-marketplace-observability.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Ops, Marketplace, and Observability Implementation
|
||||
|
||||
## Ops Modules
|
||||
|
||||
### File Manager
|
||||
- Command types: `FILE_LIST`, `FILE_READ`, `FILE_WRITE`, `FILE_UPLOAD_CHUNK`, `FILE_MOVE`, `FILE_DELETE`.
|
||||
- Security: path sandbox, denylist for system paths, content size and MIME checks.
|
||||
|
||||
### Cron Manager
|
||||
- Command types: `CRON_LIST`, `CRON_CREATE`, `CRON_UPDATE`, `CRON_DELETE`.
|
||||
- Validation: cron expression parser, command allowlist/templating, dry-run syntax checks.
|
||||
|
||||
### Firewall + Security Tools
|
||||
- Command types: `FIREWALL_RULE_ADD`, `FIREWALL_RULE_DELETE`, `SECURITY_SCAN_BASELINE`.
|
||||
- Audit: every mutation recorded with actor, reason, and approval trace.
|
||||
|
||||
### Backup & Restore
|
||||
- Command types: `BACKUP_RUN`, `BACKUP_RESTORE`, `BACKUP_VERIFY`.
|
||||
- Flows: policy-driven schedules, retention lifecycle, encrypted object storage artifacts.
|
||||
|
||||
## Plugin Marketplace
|
||||
- Catalog includes signed package metadata, compatibility matrix, and permission manifest.
|
||||
- Install pipeline:
|
||||
1. Resolve package and verify signature.
|
||||
2. Validate required capabilities and tenant entitlement.
|
||||
3. Execute install as job with rollback hooks.
|
||||
4. Persist install status and event timeline.
|
||||
|
||||
## Real-time Monitoring Dashboard
|
||||
- Live channels: CPU, RAM, disk I/O, network throughput, process health.
|
||||
- Pipeline:
|
||||
- agent collectors -> gateway ingest -> Redis stream -> metrics store.
|
||||
- UI:
|
||||
- server list health badges,
|
||||
- per-server timeline charts,
|
||||
- alert panels with acknowledgement workflow.
|
||||
|
||||
## Performance Targets
|
||||
- P95 live metric latency: < 2 seconds.
|
||||
- P95 command dispatch to agent ACK: < 1 second.
|
||||
- P95 dashboard query time (last 1 hour): < 400 ms.
|
||||
41
architecture/2026/11-identity-core-schema.sql
Normal file
41
architecture/2026/11-identity-core-schema.sql
Normal file
@@ -0,0 +1,41 @@
|
||||
-- YakPanel 2026 Identity Core additions
|
||||
|
||||
CREATE TABLE IF NOT EXISTS api_tokens (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
name varchar(80) NOT NULL,
|
||||
token_hash varchar(255) NOT NULL UNIQUE,
|
||||
scopes jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
expires_at timestamptz NULL,
|
||||
last_used_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS sessions (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
refresh_token_hash varchar(255) NOT NULL UNIQUE,
|
||||
ip inet NULL,
|
||||
user_agent text NULL,
|
||||
expires_at timestamptz NOT NULL,
|
||||
revoked_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS mfa_factors (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
factor_type varchar(24) NOT NULL,
|
||||
secret_encrypted text NOT NULL,
|
||||
recovery_codes_encrypted text NULL,
|
||||
verified_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_api_tokens_tenant_user ON api_tokens (tenant_id, user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_sessions_tenant_user ON sessions (tenant_id, user_id);
|
||||
24
architecture/2026/12-identity-phase-implementation.md
Normal file
24
architecture/2026/12-identity-phase-implementation.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Phase 2 Implementation: Identity Core
|
||||
|
||||
## Delivered
|
||||
- Identity route group in `panel-api/routes/api_v1/identity.php`.
|
||||
- Controllers for auth, tenants, and RBAC module boundaries:
|
||||
- `AuthController`
|
||||
- `TenantController`
|
||||
- `RbacController`
|
||||
- Scope evaluator service for allow/deny decision logic:
|
||||
- `ScopeEvaluator::isAllowed(...)`
|
||||
- Identity schema additions:
|
||||
- `api_tokens`
|
||||
- `sessions`
|
||||
- `mfa_factors`
|
||||
|
||||
## Behavior Contract
|
||||
- Every protected endpoint requires bearer auth middleware.
|
||||
- Access checks are explicit through RBAC grant evaluation.
|
||||
- Session/token tables support rotation, revocation, and forensic tracking.
|
||||
|
||||
## Next phase options
|
||||
- Wire persistent Eloquent models and form requests.
|
||||
- Add tenant-aware middleware that injects active tenant context.
|
||||
- Replace placeholder auth responses with JWT + refresh token issue/rotation.
|
||||
25
architecture/2026/13-server-plane-phase-implementation.md
Normal file
25
architecture/2026/13-server-plane-phase-implementation.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Phase 3 Implementation: Server Plane
|
||||
|
||||
## Delivered in this phase
|
||||
- Tenant-aware server registry controller behavior via request tenant context.
|
||||
- Agent session heartbeat intake endpoint and session repository boundary.
|
||||
- Job dispatch endpoint with command type allowlist and idempotent envelope fields.
|
||||
- Redis Streams queue adapter for Go orchestration layer.
|
||||
|
||||
## Files added/updated
|
||||
- `panel-api/app/Modules/Server/ServerRepository.php`
|
||||
- `panel-api/app/Modules/Agents/AgentSessionRepository.php`
|
||||
- `panel-api/app/Modules/Jobs/JobController.php`
|
||||
- `panel-api/app/Modules/Jobs/CommandOrchestrator.php`
|
||||
- `panel-api/app/Http/Middleware/ResolveTenantContext.php`
|
||||
- `panel-api/routes/api_v1/servers.php`
|
||||
- `panel-api/routes/api_v1/jobs.php`
|
||||
- `control-plane-go/internal/orchestration/redis_stream_queue.go`
|
||||
|
||||
## API additions
|
||||
- `POST /api/v1/servers/{server}/heartbeat`
|
||||
- `POST /api/v1/jobs/dispatch`
|
||||
|
||||
## Notes
|
||||
- Persistence adapters remain intentionally thin to keep boundary clear for full Eloquent integration.
|
||||
- Queue adapter is production-aligned with Redis Streams and can be swapped with NATS without controller changes.
|
||||
30
architecture/2026/14-server-plane-schema-additions.sql
Normal file
30
architecture/2026/14-server-plane-schema-additions.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
-- Optional server-plane extension tables
|
||||
|
||||
CREATE TABLE IF NOT EXISTS command_dispatches (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
job_id uuid NOT NULL REFERENCES jobs(id) ON DELETE CASCADE,
|
||||
server_id uuid NOT NULL REFERENCES servers(id) ON DELETE CASCADE,
|
||||
command_type varchar(64) NOT NULL,
|
||||
idempotency_key varchar(120) NOT NULL,
|
||||
status varchar(32) NOT NULL DEFAULT 'queued',
|
||||
queued_at timestamptz NOT NULL DEFAULT now(),
|
||||
dispatched_at timestamptz NULL,
|
||||
acked_at timestamptz NULL,
|
||||
finished_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, idempotency_key)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS agent_heartbeats (
|
||||
id bigserial PRIMARY KEY,
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
server_id uuid NOT NULL REFERENCES servers(id) ON DELETE CASCADE,
|
||||
agent_uid varchar(128) NOT NULL,
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_agent_heartbeats_server_created
|
||||
ON agent_heartbeats (server_id, created_at DESC);
|
||||
23
architecture/2026/15-hosting-mvp-runtime-wiring.md
Normal file
23
architecture/2026/15-hosting-mvp-runtime-wiring.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Phase 4 Implementation: Hosting MVP Runtime Wiring
|
||||
|
||||
## Delivered
|
||||
- Site/domain/SSL controllers now delegate to a single workflow service.
|
||||
- Hosting command envelopes are generated through `HostingCommandFactory`.
|
||||
- Webserver profile normalization supports:
|
||||
- `nginx`
|
||||
- `apache` (`httpd` alias)
|
||||
- `openlitespeed` (`ols` alias)
|
||||
- Command orchestrator now accepts:
|
||||
- `DOMAIN_ADD`
|
||||
- `DOMAIN_REMOVE`
|
||||
- `WEBSERVER_RELOAD`
|
||||
|
||||
## Runtime flow
|
||||
1. API receives request for site/domain/ssl mutation.
|
||||
2. `SiteWorkflowService` validates and maps request to typed command envelope.
|
||||
3. `CommandOrchestrator` assigns job metadata and enqueues dispatch payload.
|
||||
4. Execution plane consumes command and performs adapter-specific operation.
|
||||
|
||||
## Notes
|
||||
- This phase intentionally keeps persistence minimal while making runtime wiring explicit.
|
||||
- Next step is adding provider-specific validation templates and dry-run checks before dispatch.
|
||||
@@ -0,0 +1,39 @@
|
||||
# Phase 5 Implementation: Platform Operations
|
||||
|
||||
## Delivered Modules
|
||||
|
||||
### File Manager
|
||||
- API:
|
||||
- `POST /api/v1/files/list`
|
||||
- `POST /api/v1/files/read`
|
||||
- `POST /api/v1/files/write`
|
||||
- Command types:
|
||||
- `FILE_LIST`, `FILE_READ`, `FILE_WRITE`
|
||||
|
||||
### Cron Manager
|
||||
- API:
|
||||
- `GET /api/v1/cron/jobs`
|
||||
- `POST /api/v1/cron/jobs`
|
||||
- `DELETE /api/v1/cron/jobs`
|
||||
- Command types:
|
||||
- `CRON_LIST`, `CRON_CREATE`, `CRON_DELETE`
|
||||
|
||||
### Firewall
|
||||
- API:
|
||||
- `GET /api/v1/firewall/rules`
|
||||
- `POST /api/v1/firewall/rules`
|
||||
- `DELETE /api/v1/firewall/rules`
|
||||
- Command types:
|
||||
- `FIREWALL_RULE_LIST`, `FIREWALL_RULE_ADD`, `FIREWALL_RULE_DELETE`
|
||||
|
||||
### Backup and Restore
|
||||
- API:
|
||||
- `POST /api/v1/backups/run`
|
||||
- `POST /api/v1/backups/restore`
|
||||
- Command types:
|
||||
- `BACKUP_RUN`, `BACKUP_RESTORE`
|
||||
|
||||
## Implementation Notes
|
||||
- `OpsCommandFactory` centralizes operation command envelope construction.
|
||||
- `OpsWorkflowService` ensures all operations route through `CommandOrchestrator`.
|
||||
- Operation endpoints are now tenant-context aware and dispatch-ready.
|
||||
@@ -0,0 +1,30 @@
|
||||
# Phase 6 Implementation: Marketplace and Monitoring
|
||||
|
||||
## Delivered Marketplace scope
|
||||
- Added marketplace workflow and command factory:
|
||||
- `MarketplaceWorkflowService`
|
||||
- `MarketplaceCommandFactory`
|
||||
- Added marketplace controller:
|
||||
- Catalog browsing endpoint
|
||||
- Plugin install/update/remove endpoints
|
||||
- Added routes:
|
||||
- `GET /api/v1/plugin-market`
|
||||
- `POST /api/v1/plugins/install`
|
||||
- `POST /api/v1/plugins/update`
|
||||
- `POST /api/v1/plugins/remove`
|
||||
- Added command types:
|
||||
- `PLUGIN_INSTALL`
|
||||
- `PLUGIN_UPDATE`
|
||||
- `PLUGIN_REMOVE`
|
||||
|
||||
## Delivered Monitoring scope
|
||||
- Added monitoring controller:
|
||||
- `GET /api/v1/metrics/servers/{serverId}/live`
|
||||
- `POST /api/v1/alerts/rules`
|
||||
- `GET /api/v1/alerts`
|
||||
- Added ingest controller:
|
||||
- `POST /api/v1/metrics/ingest`
|
||||
|
||||
## Architecture notes
|
||||
- Marketplace lifecycle operations are routed through the same command orchestration contract as other platform operations.
|
||||
- Monitoring includes both pull-oriented live endpoint patterns and push-oriented ingest patterns for agent collectors.
|
||||
60
architecture/2026/18-saas-hardening-schema.sql
Normal file
60
architecture/2026/18-saas-hardening-schema.sql
Normal file
@@ -0,0 +1,60 @@
|
||||
-- SaaS hardening schema additions
|
||||
|
||||
CREATE TABLE IF NOT EXISTS plan_limits (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
plan_code varchar(64) NOT NULL,
|
||||
resource varchar(64) NOT NULL,
|
||||
hard_limit integer NOT NULL,
|
||||
soft_limit integer NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (plan_code, resource)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS usage_counters (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
resource varchar(64) NOT NULL,
|
||||
usage_value bigint NOT NULL DEFAULT 0,
|
||||
period_start timestamptz NOT NULL,
|
||||
period_end timestamptz NOT NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now(),
|
||||
UNIQUE (tenant_id, resource, period_start, period_end)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS webhook_endpoints (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
url text NOT NULL,
|
||||
secret_encrypted text NOT NULL,
|
||||
events jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
status varchar(32) NOT NULL DEFAULT 'active',
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS webhook_deliveries (
|
||||
id bigserial PRIMARY KEY,
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
webhook_endpoint_id uuid NOT NULL REFERENCES webhook_endpoints(id) ON DELETE CASCADE,
|
||||
event_type varchar(64) NOT NULL,
|
||||
payload jsonb NOT NULL DEFAULT '{}'::jsonb,
|
||||
status varchar(32) NOT NULL DEFAULT 'queued',
|
||||
response_code integer NULL,
|
||||
attempts integer NOT NULL DEFAULT 0,
|
||||
delivered_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public_api_tokens (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
||||
name varchar(120) NOT NULL,
|
||||
token_hash varchar(255) NOT NULL UNIQUE,
|
||||
scopes jsonb NOT NULL DEFAULT '[]'::jsonb,
|
||||
expires_at timestamptz NULL,
|
||||
revoked_at timestamptz NULL,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
);
|
||||
34
architecture/2026/19-saas-hardening-phase-implementation.md
Normal file
34
architecture/2026/19-saas-hardening-phase-implementation.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# Phase 7 Implementation: SaaS Hardening
|
||||
|
||||
## Delivered scope
|
||||
|
||||
### Quotas and plan enforcement hooks
|
||||
- Added `QuotaService` for tenant resource checks.
|
||||
- Added `BillingHooksService` for usage event emission.
|
||||
- Added APIs:
|
||||
- `POST /api/v1/saas/quotas/check`
|
||||
- `POST /api/v1/saas/usage-events`
|
||||
|
||||
### Webhook management
|
||||
- Added webhook controller for endpoint CRUD/test placeholders.
|
||||
- Added APIs:
|
||||
- `GET /api/v1/webhooks`
|
||||
- `POST /api/v1/webhooks`
|
||||
- `POST /api/v1/webhooks/test`
|
||||
|
||||
### Scoped public API
|
||||
- Added token service and public API controller.
|
||||
- Added APIs:
|
||||
- `POST /api/v1/public/tokens`
|
||||
- `POST /api/v1/public/tokens/introspect`
|
||||
|
||||
## Data model additions
|
||||
- `plan_limits`
|
||||
- `usage_counters`
|
||||
- `webhook_endpoints`
|
||||
- `webhook_deliveries`
|
||||
- `public_api_tokens`
|
||||
|
||||
## Notes
|
||||
- This phase establishes hardening boundaries and contracts.
|
||||
- Token/hash generation, secret encryption, and retry workers are the next productionization tasks.
|
||||
Reference in New Issue
Block a user