Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .devcontainer/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ RUN apt-get install -y \
vim \
htop \
jq \
locales
locales \
ripgrep


RUN sed -i '/en_US.UTF-8/s/^# //g' /etc/locale.gen && \
Expand Down
22 changes: 22 additions & 0 deletions apps/chronos/src/routes/doorlock/cards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,17 @@ export const createCardRoute = doorlockFactory.createHandlers(
export const updateCardRoute = doorlockFactory.createHandlers(
describeRoute({
description: 'Update an access card',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The access card ID.',
type: 'string',
},
},
],
requestBody: {
content: {
'application/json': {
Expand Down Expand Up @@ -320,6 +331,17 @@ export const updateCardRoute = doorlockFactory.createHandlers(
export const deleteCardRoute = doorlockFactory.createHandlers(
describeRoute({
description: 'Delete an access card',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The access card ID.',
type: 'string',
},
},
],
responses: {
200: { description: 'Card deleted' },
404: { description: 'Card not found' },
Expand Down
22 changes: 22 additions & 0 deletions apps/chronos/src/routes/doorlock/devices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ export const createDeviceRoute = doorlockFactory.createHandlers(
export const updateDeviceRoute = doorlockFactory.createHandlers(
describeRoute({
description: 'Update an existing doorlock device',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The doorlock device ID.',
type: 'string',
},
},
],
requestBody: {
content: {
'application/json': {
Expand Down Expand Up @@ -216,6 +227,17 @@ export const updateDeviceRoute = doorlockFactory.createHandlers(
export const deleteDeviceRoute = doorlockFactory.createHandlers(
describeRoute({
description: 'Delete a doorlock device',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The doorlock device ID.',
type: 'string',
},
},
],
responses: {
200: { description: 'Device deleted' },
},
Expand Down
11 changes: 11 additions & 0 deletions apps/chronos/src/routes/doorlock/ota.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,17 @@ const otaPayloadSchema = z.object({
export const triggerDeviceOtaRoute = doorlockFactory.createHandlers(
describeRoute({
description: 'Trigger an OTA update on a specific device',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The doorlock device ID.',
type: 'string',
},
},
],
requestBody: {
content: {
'application/json': {
Expand Down
22 changes: 22 additions & 0 deletions apps/chronos/src/routes/doorlock/self.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ export const listSelfCardsRoute = doorlockFactory.createHandlers(
export const updateSelfCardFrozenRoute = doorlockFactory.createHandlers(
describeRoute({
description: 'Update the frozen state of a user-owned card',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The user-owned card ID.',
type: 'string',
},
},
],
requestBody: {
content: {
'application/json': {
Expand Down Expand Up @@ -162,6 +173,17 @@ export const activateVirtualCardRoute = doorlockFactory.createHandlers(
describeRoute({
description:
'Activate an authorized device using a user-owned virtual card',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The user-owned card ID.',
type: 'string',
},
},
],
requestBody: {
content: {
'application/json': {
Expand Down
11 changes: 11 additions & 0 deletions apps/chronos/src/routes/doorlock/stats.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,17 @@ export const doorlockStatsRoute = doorlockFactory.createHandlers(
export const deviceStatsRoute = doorlockFactory.createHandlers(
describeRoute({
description: 'Get device health statistics',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: {
description: 'The doorlock device ID.',
type: 'string',
},
},
],
responses: {
200: {
content: {
Expand Down
25 changes: 25 additions & 0 deletions apps/chronos/src/routes/doorlock/websocket-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import type { ServerWebSocket } from 'bun';
import { and, eq } from 'drizzle-orm';
import { upgradeWebSocket } from 'hono/bun';
import { HTTPException } from 'hono/http-exception';
import { describeRoute } from 'hono-openapi';
import { z } from 'zod';
import { db } from '#database';
import {
Expand Down Expand Up @@ -181,6 +182,30 @@ export const syncDatabase = async (deviceId: string) => {
};

export const websocketHandler = doorlockFactory.createHandlers(
describeRoute({
description:
'Upgrade an authenticated device connection to WebSocket for doorlock events.',
parameters: [
{
in: 'header',
name: 'X-Aegis-Device-Token',
required: true,
schema: {
description: 'Device API token used for WebSocket authentication.',
type: 'string',
},
},
],
responses: {
101: {
description: 'Switching Protocols',
},
401: {
description: 'Invalid or missing device token',
},
},
tags: ['Doorlock'],
}),
async (c, next) => {
const gotToken = c.req.header('X-Aegis-Device-Token');
if (!gotToken) {
Expand Down
44 changes: 44 additions & 0 deletions apps/chronos/src/routes/news/announcements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ export const listAnnouncements = newsFactory.createHandlers(
describeRoute({
description:
'List active announcements within date range, filtered by user cohort',
parameters: [
{
in: 'query',
name: 'limit',
required: false,
schema: { default: 20, minimum: 1, type: 'number' },
},
{
in: 'query',
name: 'offset',
required: false,
schema: { default: 0, minimum: 0, type: 'number' },
},
{
in: 'query',
name: 'includeExpired',
required: false,
schema: { default: false, type: 'boolean' },
},
],
responses: {
200: {
content: {
Expand Down Expand Up @@ -166,6 +186,14 @@ export const listAnnouncements = newsFactory.createHandlers(
export const getAnnouncement = newsFactory.createHandlers(
describeRoute({
description: 'Get a single announcement by ID',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: { format: 'uuid', type: 'string' },
},
],
responses: {
200: {
content: {
Expand Down Expand Up @@ -293,6 +321,14 @@ export const createAnnouncement = newsFactory.createHandlers(
export const updateAnnouncement = newsFactory.createHandlers(
describeRoute({
description: 'Update an existing announcement',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: { format: 'uuid', type: 'string' },
},
],
requestBody: {
content: {
'application/json': {
Expand Down Expand Up @@ -406,6 +442,14 @@ export const updateAnnouncement = newsFactory.createHandlers(
export const deleteAnnouncement = newsFactory.createHandlers(
describeRoute({
description: 'Delete an announcement',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: { format: 'uuid', type: 'string' },
},
],
responses: {
200: {
content: {
Expand Down
44 changes: 44 additions & 0 deletions apps/chronos/src/routes/news/blogs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ const checkSlugExists = async (slug: string, excludeId?: string) => {
export const listPublishedBlogs = newsFactory.createHandlers(
describeRoute({
description: 'List published blog posts (public, no auth required)',
parameters: [
{
in: 'query',
name: 'limit',
required: false,
schema: { default: 20, minimum: 1, type: 'number' },
},
{
in: 'query',
name: 'offset',
required: false,
schema: { default: 0, minimum: 0, type: 'number' },
},
],
responses: {
200: {
content: {
Expand Down Expand Up @@ -123,6 +137,14 @@ export const listPublishedBlogs = newsFactory.createHandlers(
export const getBlogBySlug = newsFactory.createHandlers(
describeRoute({
description: 'Get a published blog post by slug (public, no auth required)',
parameters: [
{
in: 'path',
name: 'slug',
required: true,
schema: { type: 'string' },
},
],
responses: {
200: {
content: {
Expand Down Expand Up @@ -173,6 +195,20 @@ export const getBlogBySlug = newsFactory.createHandlers(
export const listDrafts = newsFactory.createHandlers(
describeRoute({
description: 'List all blog posts including drafts (requires permission)',
parameters: [
{
in: 'query',
name: 'limit',
required: false,
schema: { default: 20, minimum: 1, type: 'number' },
},
{
in: 'query',
name: 'offset',
required: false,
schema: { default: 0, minimum: 0, type: 'number' },
},
],
responses: {
200: {
content: {
Expand Down Expand Up @@ -225,6 +261,14 @@ export const getBlogById = newsFactory.createHandlers(
describeRoute({
description:
'Get any blog post by ID including drafts (requires permission)',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: { format: 'uuid', type: 'string' },
},
],
responses: {
200: {
content: {
Expand Down
36 changes: 36 additions & 0 deletions apps/chronos/src/routes/news/system-messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,26 @@ export const listSystemMessages = newsFactory.createHandlers(
describeRoute({
description:
'List active system messages within date range, filtered by user cohort',
parameters: [
{
in: 'query',
name: 'limit',
required: false,
schema: { default: 20, minimum: 1, type: 'number' },
},
{
in: 'query',
name: 'offset',
required: false,
schema: { default: 0, minimum: 0, type: 'number' },
},
{
in: 'query',
name: 'includeExpired',
required: false,
schema: { default: false, type: 'boolean' },
},
],
responses: {
200: {
content: {
Expand Down Expand Up @@ -163,6 +183,14 @@ export const listSystemMessages = newsFactory.createHandlers(
export const getSystemMessage = newsFactory.createHandlers(
describeRoute({
description: 'Get a single system message by ID',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: { format: 'uuid', type: 'string' },
},
],
responses: {
200: {
content: {
Expand Down Expand Up @@ -290,6 +318,14 @@ export const createSystemMessage = newsFactory.createHandlers(
export const updateSystemMessage = newsFactory.createHandlers(
describeRoute({
description: 'Update an existing system message',
parameters: [
{
in: 'path',
name: 'id',
required: true,
schema: { format: 'uuid', type: 'string' },
},
],
requestBody: {
content: {
'application/json': {
Expand Down
Loading
Loading