Skip to content

Latest commit

 

History

History
303 lines (233 loc) · 6.47 KB

File metadata and controls

303 lines (233 loc) · 6.47 KB

API and CLI

Kelompok should be API-first and CLI-first.

The web app, automation jobs, service integrations, and future AI workflows should use the same core API and command interfaces.

API Principles

  • Version all public endpoints under /api/v1
  • Return consistent response shapes
  • Use cursor pagination for large public lists
  • Keep public endpoints readable without authentication
  • Require authentication for claims, edits, campaigns, and admin actions
  • Make claim, import, and enrichment operations auditable
  • Publish OpenAPI docs
  • Expose plugin-safe ingestion endpoints and commands
  • Return public DTOs instead of raw database models
  • Keep claim-only contact data, source evidence, raw imports, and private plugin metadata out of public responses

Response Shape

Recommended success shape:

{
  "data": {},
  "meta": {},
  "message": "ok"
}

Recommended error shape:

{
  "error": {
    "code": "organization_not_found",
    "message": "Organization not found",
    "details": {}
  }
}

Public Endpoints

Public endpoints must be treated as an explicit allowlist.

They may include public organization profile fields, public post fields, and public impact metrics. They must not expose internal UUIDs, claim verification emails, raw source records, private evidence, credentials, tokens, or plugin-private metadata.

Dynamic JSON fields are filtered before they leave the API. If a plugin or import pipeline needs to keep raw evidence, it should store that data in internal tables or private JSON fields and expose only reviewed public fields through the stable response DTO.

Organizations:

GET /api/v1/organizations
GET /api/v1/organizations/{slug}
GET /api/v1/organizations/{slug}/events
GET /api/v1/organizations/{slug}/donations
GET /api/v1/organizations/{slug}/impact-reports
GET /api/v1/organizations/{slug}/posts
GET /api/v1/organizations/{slug}/posts/{post_slug}
GET /api/v1/organizations/{slug}/sdgs

Implemented in the first public read API slice:

GET /api/v1/organizations
GET /api/v1/organizations/{slug}
GET /api/v1/organizations/{slug}/posts
GET /api/v1/organizations/{slug}/posts/{post_slug}
GET /api/v1/organizations/{slug}/impact-reports

Posts:

GET /api/v1/posts
GET /api/v1/posts/{slug}
GET /api/v1/post-categories
GET /api/v1/post-tags

Implemented in the first public read API slice:

GET /api/v1/posts
GET /api/v1/posts/{slug}

Events:

GET /api/v1/events
GET /api/v1/events/{slug}
POST /api/v1/events/{event_id}/registrations

Donation campaigns:

GET /api/v1/donation-campaigns
GET /api/v1/donation-campaigns/{slug}
GET /api/v1/donation-campaigns/{slug}/reports

Authenticated Endpoints

Auth:

POST /api/v1/auth/register
POST /api/v1/auth/login
POST /api/v1/auth/logout
GET /api/v1/auth/me

Claims:

POST /api/v1/organizations/{id}/claims
GET /api/v1/claims
GET /api/v1/claims/{id}
POST /api/v1/claims/{id}/verify-email
POST /api/v1/claims/{id}/verify-instagram
POST /api/v1/admin/claims/{id}/approve
POST /api/v1/admin/claims/{id}/reject

Organization management:

PATCH /api/v1/org-admin/organizations/{id}
POST /api/v1/org-admin/organizations/{id}/members
PATCH /api/v1/org-admin/organizations/{id}/members/{member_id}
DELETE /api/v1/org-admin/organizations/{id}/members/{member_id}
POST /api/v1/org-admin/organizations/{id}/impact-reports
PATCH /api/v1/org-admin/impact-reports/{id}

Post management:

POST /api/v1/org-admin/posts
PATCH /api/v1/org-admin/posts/{id}
POST /api/v1/org-admin/posts/{id}/publish
POST /api/v1/org-admin/posts/{id}/archive

Event management:

POST /api/v1/org-admin/events
PATCH /api/v1/org-admin/events/{id}
POST /api/v1/org-admin/events/{id}/ticket-types
GET /api/v1/org-admin/events/{id}/registrations

Donor management:

POST /api/v1/org-admin/donation-campaigns
PATCH /api/v1/org-admin/donation-campaigns/{id}
POST /api/v1/org-admin/donation-campaigns/{id}/reports
PATCH /api/v1/org-admin/donation-reports/{id}

CLI Principles

The CLI should be useful for:

  • Local development
  • Self-hosted maintenance
  • Data imports
  • Import and enrichment jobs
  • Claim operations
  • Exporting data
  • Future AI agent workflows

CLI commands should support:

  • --json output
  • --dry-run
  • --limit
  • --source
  • --since
  • clear exit codes

Proposed CLI Commands

Server and database:

kelompok serve
kelompok migrate up
kelompok migrate down
kelompok seed
kelompok health

Implemented early:

kelompok seed demo

Organization data:

kelompok org import --file organizations.csv
kelompok org search "climate foundation"
kelompok org show {slug} --json
kelompok org claim {slug} --email admin@example.org
kelompok org export --format json

Members:

kelompok member import --file members.csv --organization {slug}
kelompok member export --organization {slug} --format json

Posts:

kelompok post import --file posts.csv --organization {slug}
kelompok post publish {id}
kelompok post archive {id}
kelompok post export --organization {slug} --format json

Imports and source operations:

kelompok source add --type website --url https://example.org
kelompok source normalize --source-record {id}
kelompok source match --dry-run

Plugins:

kelompok plugin list
kelompok plugin info {plugin}
kelompok plugin run {plugin} --job import-organizations --file organizations.csv
kelompok plugin run {plugin} --job import-members --organization {slug}
kelompok plugin run {plugin} --job import-posts --organization {slug}
kelompok plugin run {plugin} --job import-events --organization {slug}

Events:

kelompok event import --file events.csv
kelompok event publish {id}

Donor reports:

kelompok donor campaign create
kelompok donor report publish {id}
kelompok donor export --organization {slug}

Admin:

kelompok admin user create
kelompok admin claim approve {claim_id}
kelompok admin claim reject {claim_id}
kelompok admin audit show --entity organization:{id}

AI-Ready CLI Contract

For future AI usage, CLI output should be deterministic and machine-readable.

Example:

kelompok org show green-foundation --json

Should return:

{
  "id": "org_123",
  "slug": "green-foundation",
  "name": "Green Foundation",
  "claim_status": "unclaimed",
  "public_url": "https://example.org/o/green-foundation",
  "sdgs": ["13", "15"],
  "sources": [
    {
      "type": "website",
      "url": "https://green.example.org"
    }
  ]
}