import { Activity, Company, CompanyFilters, Contact, ContactFilters, CreateActivityInput, CreateCompanyInput, CreateContactInput, CreateDealInput, CreateTaskInput, Deal, Page, PageRequest, RecordSource, Task, TaskFilters, UpdateCompanyInput, UpdateContactInput, UpdateDealInput, UpdateTaskInput } from "./types.mjs"; //#region src/adapter.d.ts /** * The contract every ORM implementation fulfils. `packages/drizzle` is the first * implementation; Prisma/Kysely/TypeORM can follow without changes to consumers. * * Every method is scoped to a single organization (`orgId`) — the adapter is the * one place tenant isolation is enforced for CRM data. Implementations only ever * read/write Clivly-owned `crm_*` tables; they never mutate host business tables. */ export interface CRMAdapter { /** * Soft-delete: sets `archivedAt` so the row drops out of lists while the * deals, activities and tasks that reference it keep resolving. Mirrors the * sync engine's archive-on-leave doctrine — a contact that disappears from * the host view is archived, never deleted, for exactly this reason. */ archiveCompany(orgId: string, id: string): Promise; archiveContact(orgId: string, id: string): Promise; archiveTask(orgId: string, id: string): Promise; completeTask(orgId: string, id: string): Promise; createActivity(orgId: string, data: CreateActivityInput): Promise; createCompany(orgId: string, data: CreateCompanyInput): Promise; createContact(orgId: string, data: CreateContactInput): Promise; createDeal(orgId: string, data: CreateDealInput): Promise; createTask(orgId: string, data: CreateTaskInput): Promise; deleteDeal(orgId: string, id: string): Promise; getActivities(orgId: string, contactId: string): Promise; getCompanies(orgId: string, filters?: CompanyFilters): Promise; /** * The companies named by `ids`, for resolving a page of contacts to company * names. * * `contacts.list` used to build that map from `getCompanies(orgId)` — every * company in the org, to label at most one per listed contact. Scoping the * fetch to the ids actually referenced keeps a bounded page of contacts from * dragging an unbounded sibling query behind it. * * Returns only the rows that exist; a missing id is not an error, because a * contact can reference a company archived since the page was built. */ getCompaniesByIds(orgId: string, ids: string[]): Promise; getCompany(orgId: string, id: string): Promise; getContact(orgId: string, id: string): Promise; getContacts(orgId: string, filters?: ContactFilters): Promise; /** * The contacts named by `ids`, for resolving a page of deals to contact * names. See {@link CRMAdapter.getCompaniesByIds} — `deals.list` had the * same unbounded-sibling problem. * * Deliberately unfiltered by archive state: a live deal pointing at an * archived contact must still render that contact's name, which is the same * reason `deals.list` never passed `excludeArchived` to `getContacts`. */ getContactsByIds(orgId: string, ids: string[]): Promise; getDeal(orgId: string, id: string): Promise; getDeals(orgId: string, filters?: { source?: RecordSource; }): Promise; getTasks(orgId: string, filters?: TaskFilters): Promise; /** * One page of companies, newest first. * * Separate from `getCompanies` rather than a `limit` on `CompanyFilters`, * and that is the whole point: an optional field on a shared filter type is * silently inheritable, and the callers that must never inherit it are the * ones where truncation corrupts data rather than merely hiding rows. * `importContacts` builds its dedup set from the unpaged read — a truncated * set resurrects a contact archived as a duplicate. A distinct method makes * "this call is paginated" a decision at every call site. */ listCompaniesPage(orgId: string, filters?: CompanyFilters, page?: PageRequest): Promise>; /** One page of contacts, newest first. See {@link CRMAdapter.listCompaniesPage}. */ listContactsPage(orgId: string, filters?: ContactFilters, page?: PageRequest): Promise>; /** One page of deals, newest first. See {@link CRMAdapter.listCompaniesPage}. */ listDealsPage(orgId: string, filters?: { source?: RecordSource; }, page?: PageRequest): Promise>; /** * Move a deal to `stage` and reorder it directly after `afterId` (null = top * of the column). The adapter computes the fractional `position` from the * target column's current order; callers never pass a numeric position. */ moveDeal(orgId: string, id: string, stage: Deal["stage"], afterId: string | null): Promise; reopenTask(orgId: string, id: string): Promise; /** * Clear `archivedAt`, putting the row back in the lists. The inverse of * `archiveCompany` / `archiveContact`, and what an "Undo" on an archive * toast calls — archiving is reversible, so the UI should be able to say so. */ unarchiveCompany(orgId: string, id: string): Promise; unarchiveContact(orgId: string, id: string): Promise; updateCompany(orgId: string, id: string, data: UpdateCompanyInput): Promise; updateContact(orgId: string, id: string, data: UpdateContactInput): Promise; updateDeal(orgId: string, id: string, data: UpdateDealInput): Promise; updateDealStage(orgId: string, id: string, stage: Deal["stage"]): Promise; updateTask(orgId: string, id: string, data: UpdateTaskInput): Promise; updateTaskStatus(orgId: string, id: string, status: Task["status"]): Promise; } //#endregion