feat: initialize ingest-api with Koa and telemetry handling
- Create ingest-api with Koa framework for handling device telemetry. - Implement telemetry ingestion with MongoDB, Redis, and PostgreSQL. - Add API endpoints for telemetry and health checks. - Set up testing with Vitest for unit and end-to-end tests. - Configure Prettier and ESLint for code formatting and linting. - Create Docker Compose setup for PostgreSQL, MongoDB, and Redis services. - Establish contracts package for shared Zod schemas and TypeScript types. - Implement React frontend with device status and greeting functionalities. - Add VS Code setup documentation for onboarding developers.
This commit is contained in:
1 parent
534fa6dc51
commit
7923ba1b8d
70 files changed
+3085
-3434
No files matched your search
@@ -0,0 +1,5 @@
|
||||
# contracts
|
||||
|
||||
Zod schemas and TypeScript types shared by ingest-api, crud-api, and web.
|
||||
|
||||
This package depends on **zod only**. Do not add Koa, Express, Mongo, or trest here — the frontend workspace should stay installable with `yarn workspaces focus web`.
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "contracts",
|
||||
"private": true,
|
||||
"version": "0.0.1",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"zod": "^3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const deviceStatusSourceSchema = z.enum(['postgres', 'redis', 'missing']);
|
||||
|
||||
export const deviceStatusSchema = z.object({
|
||||
deviceId: z.string().min(1),
|
||||
lastSeen: z.string().datetime().nullable(),
|
||||
payload: z.record(z.unknown()),
|
||||
online: z.boolean(),
|
||||
source: deviceStatusSourceSchema,
|
||||
ageMs: z.number().int().nonnegative().nullable(),
|
||||
});
|
||||
|
||||
export const deviceStatusPairSchema = z.object({
|
||||
postgres: deviceStatusSchema,
|
||||
redis: deviceStatusSchema,
|
||||
});
|
||||
|
||||
export type DeviceStatus = z.infer<typeof deviceStatusSchema>;
|
||||
export type DeviceStatusPair = z.infer<typeof deviceStatusPairSchema>;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const greetingQuerySchema = z.object({
|
||||
name: z.string().min(1),
|
||||
});
|
||||
|
||||
export const greetingOutputSchema = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
export type GreetingQuery = z.infer<typeof greetingQuerySchema>;
|
||||
export type GreetingOutput = z.infer<typeof greetingOutputSchema>;
|
||||
@@ -0,0 +1,4 @@
|
||||
export * from './device-status.js';
|
||||
export * from './greeting.js';
|
||||
export * from './presence.js';
|
||||
export * from './telemetry.js';
|
||||
@@ -0,0 +1,4 @@
|
||||
/** Redis TTL and Postgres "online" window for the demo. */
|
||||
export const PRESENCE_TTL_SECONDS = 15;
|
||||
|
||||
export const DEMO_DEVICE_ID = 'dev-1';
|
||||
@@ -0,0 +1,11 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const telemetryPayloadSchema = z.record(z.unknown());
|
||||
|
||||
export const telemetryIngestSchema = z.object({
|
||||
deviceId: z.string().min(1),
|
||||
sentAt: z.string().datetime(),
|
||||
payload: telemetryPayloadSchema,
|
||||
});
|
||||
|
||||
export type TelemetryIngest = z.infer<typeof telemetryIngestSchema>;
|
||||
Reference in new issue
Block a user