expand manual prospect intelligence workflows
This commit is contained in:
+47
-11
@@ -1,6 +1,6 @@
|
||||
# Prospect Platform API MVP
|
||||
# Prospect Platform API — Phase 3
|
||||
|
||||
Dependency-light JSON API for a single demo tenant (`demo-tenant`). Core domain rules use only Python's standard library; persistence is SQLite. This MVP stores prospect evidence and scores, but never sends outreach.
|
||||
Dependency-light JSON API for tenant-scoped, **manual** prospect workflows. Core domain rules use Python's standard library and persistence is SQLite. The API stores businesses plus child intelligence/evidence records, pipeline state, notes, and audit context. It never performs automated discovery, DNS/website scanning, or outreach.
|
||||
|
||||
## Run
|
||||
|
||||
@@ -14,14 +14,50 @@ python3 -m unittest discover
|
||||
|
||||
Set `PROSPECT_API_PORT` or pass `--port`; set `PROSPECT_API_DB` or pass `--db` to override the default `prospects.db`.
|
||||
|
||||
## Endpoints
|
||||
## Endpoint contract
|
||||
|
||||
- `GET /api/v1/health/live` — liveness.
|
||||
- `GET /api/v1/dashboard/summary` — tenant-scoped counts and score average.
|
||||
- `GET /api/v1/businesses` — list businesses; optional `?q=` filter.
|
||||
- `POST /api/v1/businesses` — create a business from JSON (`name` required; website, email, phone, description optional). Normalization, scoring, deduplication, and suppression are enforced server-side.
|
||||
- `GET /api/v1/businesses/{id}` — retrieve one tenant-scoped business.
|
||||
- `POST /api/v1/suppressions` — add `{kind: email|domain|phone, value: ...}`. Future matching business creation is blocked.
|
||||
- `POST /api/v1/imports/preview` — preview `{rows: [...]}` without writing; reports accepted, duplicates, suppressed, normalized rows.
|
||||
All protected endpoints require the server-side session cookie. Every query is constrained by the authenticated user's `organization_id`; IDs from another tenant behave as not found and must not disclose whether a record exists.
|
||||
|
||||
All SQL uses parameters and all responses are JSON. Scores include `score_version` and `score_factors` for traceability. There is intentionally no send/outreach endpoint.
|
||||
### Health and workspace
|
||||
|
||||
- `GET /api/v1/health/live` — unauthenticated liveness check.
|
||||
- `GET /api/v1/auth/me` — current authenticated user and tenant.
|
||||
- `GET /api/v1/dashboard/summary` — tenant-scoped counts and score summary.
|
||||
|
||||
### Prospect and child intelligence records
|
||||
|
||||
- `GET /api/v1/businesses` — paginated tenant list. Supports bounded `page`/`page_size`, text `q`, `score_min`/`score_max`, `website_class`, and `pipeline_stage` filters, with stable ordering. Responses contain `items`, `page`, `page_size`, and `has_next`; callers must not assume all records are returned.
|
||||
- `POST /api/v1/businesses` — manual business creation. `name` is required; website, email, phone, description, and other explicitly supported intake fields are optional. Normalization, scoring, deduplication, and suppression are enforced server-side.
|
||||
- `GET /api/v1/businesses/{id}` — tenant-scoped business detail, including the permitted child intelligence/evidence projection and current pipeline/review context.
|
||||
The business detail includes the supported child collections: `contacts`, `domains`, `websites`, `evidence`, `pipeline`, and `notes`. The child collection routes are:
|
||||
|
||||
- `POST /api/v1/businesses/{id}/contacts` — manually add a contact; suppression matching marks a matching contact as do-not-contact.
|
||||
- `POST /api/v1/businesses/{id}/domains` — manually add a domain observation.
|
||||
- `POST /api/v1/businesses/{id}/websites` — manually add a website observation/classification.
|
||||
- `POST /api/v1/businesses/{id}/evidence` — manually add evidence with its kind, claim, and source URL/reference. This records provenance supplied by the operator; it does not scan or independently verify the URL.
|
||||
- `POST /api/v1/businesses/{id}/notes` — add a manual note.
|
||||
|
||||
Child records are subordinate to their parent business. A child ID is never sufficient authorization: the API verifies both the child ID and the parent business's organization. Do not use a missing source or a score as proof that a website or DNS check occurred.
|
||||
|
||||
### Pipeline, verification, and audit behavior
|
||||
|
||||
- `POST /api/v1/businesses/{id}/pipeline` — record an allowed human workflow-stage transition, with server-side validation and an audit event.
|
||||
- `POST /api/v1/businesses/{id}/verify` — record the permitted human verification action and its audit event; it does not perform an external check.
|
||||
- Each business detail response returns the tenant-scoped child collections and current verification/pipeline context. Audit events are retained in the workspace audit log; the detail projection includes the relevant mutation context where supported.
|
||||
|
||||
Pipeline state and verification are review metadata, not outreach authorization. Suppression always wins, and the API exposes no send/contact endpoint. State changes, child records, and notes are human-entered; they do not trigger discovery, scanning, or outbound messaging.
|
||||
|
||||
### Existing safety and intake routes
|
||||
|
||||
- `POST /api/v1/suppressions` — add `{kind: email|domain|phone, value: ...}` for the current tenant. Future matching business creation is blocked.
|
||||
- `POST /api/v1/imports/preview` — preview `{rows: [...]}` without writing; reports accepted, duplicates, suppressed, and normalized rows. It is not an import/persistence endpoint.
|
||||
|
||||
All SQL uses parameters and all responses are JSON. Scores include `score_version` and `score_factors` for traceability. Provenance is supplied by the operator/source record; the MVP does not validate external sources or independently refresh evidence.
|
||||
|
||||
## Pagination and filtering rules
|
||||
|
||||
List and child-record endpoints are deliberately bounded. For business lists, use `page` (starting at 1) and `page_size` within the server-enforced maximum; invalid values are rejected rather than allowing an unbounded query. Supported filters are applied inside the tenant-scoped query before pagination: `q`, `score_min`, `score_max`, `website_class`, and `pipeline_stage`. The UI's page and filter controls are convenience clients, not authorization controls. A filtered page is not a count of the entire unfiltered tenant unless the response explicitly says so.
|
||||
|
||||
## Remaining limitations
|
||||
|
||||
SQLite is a pilot store with no production migration runner, queue, scheduler, durable backup command, or tested restore workflow. Authentication currently uses a development password fallback and does not by itself provide production Argon2id, MFA, CSRF protection, rate limiting, or a complete retention-grade audit system. Automated discovery, DNS/HTTP scanning, and outreach remain explicitly out of scope.
|
||||
|
||||
Reference in New Issue
Block a user