crea-ddf
v0.0.6
Published
An Effect Native Typescript SDK for the CREA DDF API with Postgres sync and frontend-ready database queries.
Maintainers
Readme
CREA DDF
CREA DDF is a TypeScript package for working with the CREA DDF API, syncing the feed into Postgres, and reading that synced data from frontend applications.
The core flow is:
CREA DDF API -> syncDdfDatabaseOnce -> Postgres/Drizzle tables -> DdfDbClient -> frontendYou can still use the API client directly for live DDF reads, but the normal application path is now database-first: run the sync job, store the normalized listing/member/office/open-house data, then let the frontend query the local database through the exported DB client.
Requirements
- Bun
1.3.0or newer - Node.js
24.14.0or newer - PostgreSQL
- CREA DDF API credentials
Install
bun installThe install runs the Effect TypeScript patch through the package prepare script. Keep that in place; the Effect LSP warnings are useful and catch real SDK mistakes.
Environment
Create a local .env file or export these variables in your shell:
DATABASE_URL="postgres://user:password@localhost:5432/crea_ddf"
CREA_DDF_CLIENT_ID="your-client-id"
CREA_DDF_CLIENT_SECRET="your-client-secret"
# Optional defaults
CREA_DDF_BASE_URL="https://ddfapi.realtor.ca"
CREA_DDF_AUTH_URL="https://identity.crea.ca/connect/token"
CREA_ANALYTICS_URL=""
# Optional database-sync scope. Accepts comma-separated values or a JSON array.
CREA_CHOSEN_AOR_KEYS="76,77,93"CREA_DDF_BASE_URL should be the API host only, not /odata/v1.
Database Setup
Run migrations before the first sync:
bun run db:migrateUseful database commands:
bun run db:generate
bun run db:push
bun run db:studiodb:generate creates migrations after schema changes. db:migrate applies the checked-in migrations. db:studio opens Drizzle Studio against DATABASE_URL.
Sync DDF To Postgres
Run a full database sync with file telemetry:
bun run sync:otelThat command:
- authenticates with CREA DDF
- runs database migrations
- syncs destinations, properties, members, offices, and open houses
- saves database watermarks for incremental property/member/office sync
- records sync runs and sync errors
- writes logs, spans, and Prometheus-style metrics under
.otel/
Open houses do not have a DDF replication endpoint, so they are synced from the listings already stored in the database and default to a 30-day date window.
Read Synced Data In A Frontend
Use the ./db export in server loaders, API routes, or other backend code that feeds the frontend. The frontend should query your app server; it should not receive CREA credentials.
import { Effect, Layer } from "effect";
import { DdfDatabase, DdfDbClient } from "crea-ddf/db";
const dbReadLayer = DdfDbClient.layer.pipe(
Layer.provide(DdfDatabase.layerConfig),
);
const listingsForSearchPage = Effect.gen(function* () {
const ddf = yield* DdfDbClient;
return yield* ddf.properties.list({
filters: {
active: true,
city: "Toronto",
province: "Ontario",
minBedrooms: 2,
},
include: {
media: { select: ["mediaUrl", "preferredPhoto"] },
listOffice: { select: ["officeName", "phone"] },
},
limit: 24,
orderBy: [{ field: "modificationTimestamp", direction: "desc" }],
});
}).pipe(Effect.provide(dbReadLayer));The database client also exposes members, offices, openHouses, and destinations, with typed filters, field projections, pagination, and includes.
Use The Live API Client
For direct DDF API reads, provide the DDF layer and call the resource helpers:
import { Effect } from "effect";
import { listProperties, makeDdfLayerFromEnv } from "crea-ddf";
const program = Effect.gen(function* () {
return yield* listProperties({
top: 10,
orderby: ["ModificationTimestamp desc", "ListingKey asc"],
});
}).pipe(Effect.provide(makeDdfLayerFromEnv));Prefer the database path for frontend search and detail pages once sync is enabled.
Development
bun run typecheck
bun run test
bun run build
bun run check:metadataLive CREA checks are opt-in and require credentials:
bun run test:liveGenerated build output goes to dist/. Database migrations are copied to dist/db/migrations during bun run build so the published package can run migrations at runtime.
Docs
Start with @docs/README.md for the full SDK/API guide and @docs/09-current-implementation.md for the current package, runtime, database, sync, telemetry, and test status.
Author
Built by Warya Wayne, @waryawayne.
- GitHub: @WaryaWayne
- X: @waryawayne
