6a6cd76426
Minimal Go service so platform/portal has something to resolve in local
dev. Stdlib net/http with Go 1.22 enhanced ServeMux (method+path
patterns); no third-party deps yet.
Layout:
cmd/server/main.go entry point with graceful shutdown
internal/config/ env-driven config (APP_ENV, ADDR, KC issuer)
internal/server/ http handlers + request-logging middleware
internal/store/memory.go in-memory tenant store, seeded with acme
migrations/0001_init.up.sql schema for the M4.1 follow-up (unapplied)
Makefile dev/test/build/lint/docker targets
Dockerfile multi-stage distroless build
Endpoints (under :8080 in dev):
GET /healthz
GET /v1/tenants/by-slug/{slug} 200 acme | 404
GET /v1/tenants/{id} 200 by uuid | 404
JWT validation and the real Postgres-backed store land in the M4.1
follow-up PR — keeping this PR strictly to 'boots, replies, tests pass'.
Refs: M4.1 (skeleton)
53 lines
1.9 KiB
SQL
53 lines
1.9 KiB
SQL
-- Placeholder for the M4.1 schema (see PLATFORM_ARCHITECTURE.md §5c).
|
|
-- The skeleton uses an in-memory store; this file lands the table shape
|
|
-- the real M4.1 PR will use, so the schema review can happen alongside
|
|
-- the rest of the boot scaffolding.
|
|
|
|
-- enums --------------------------------------------------------------------
|
|
|
|
CREATE TYPE tenant_status AS ENUM ('trial', 'active', 'frozen', 'archived', 'demo');
|
|
CREATE TYPE tenant_kind AS ENUM ('customer', 'demo', 'stage', 'internal');
|
|
|
|
-- tenants ------------------------------------------------------------------
|
|
|
|
CREATE TABLE tenants (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
slug TEXT UNIQUE NOT NULL CHECK (slug ~ '^[a-z0-9-]{2,40}$'),
|
|
name TEXT NOT NULL,
|
|
status tenant_status NOT NULL DEFAULT 'trial',
|
|
kind tenant_kind NOT NULL DEFAULT 'customer',
|
|
plan TEXT NOT NULL DEFAULT 'starter',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
trial_ends_at TIMESTAMPTZ
|
|
);
|
|
|
|
CREATE INDEX tenants_status_idx ON tenants (status);
|
|
|
|
-- tenant ↔ product entitlements -------------------------------------------
|
|
|
|
CREATE TABLE tenant_products (
|
|
tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
|
|
product TEXT NOT NULL,
|
|
enabled BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
PRIMARY KEY (tenant_id, product)
|
|
);
|
|
|
|
-- audit log (Retraced-shape; PRODUCT_INTEGRATION_SPEC.md §8.4) ------------
|
|
|
|
CREATE TABLE audit_log (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
tenant_id UUID REFERENCES tenants(id),
|
|
actor_id TEXT,
|
|
actor_name TEXT,
|
|
action TEXT NOT NULL,
|
|
target_id TEXT,
|
|
target_type TEXT,
|
|
metadata JSONB NOT NULL DEFAULT '{}'::jsonb,
|
|
source_ip INET,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
);
|
|
|
|
CREATE INDEX audit_log_tenant_idx ON audit_log (tenant_id, created_at DESC);
|