feat(api): implement chestny-znak web app with True API integration

- Fastify backend with auth (CryptoPro CAdES-BES), KM check, UPD parsing
- React frontend with auth page, code check, XML upload, results table
- Client-side signing via crypto-pro 2.3.0 (browser plugin)
- Token caching with auto-refresh, retry with exponential backoff
- Input validation schemas, file size limits, global 401 interceptor
- Docker compose with backend + frontend (nginx) services
This commit is contained in:
kislovdm
2026-07-08 16:53:35 +03:00
parent d2819ff03c
commit 70eac33c8c
19 changed files with 501 additions and 240 deletions
+26 -4
View File
@@ -1,13 +1,35 @@
import type { FastifyInstance } from 'fastify'
import { checkCodesPublic, checkCodesAuth } from '../services/cises-service.js'
import { checkCodesPublic, checkCodesAuth, AppError } from '../services/cises-service.js'
import type { CheckCodesRequest } from '../types/index.js'
const checkCodesSchema = {
body: {
type: 'object',
required: ['codes'],
properties: {
codes: {
type: 'array',
items: { type: 'string', minLength: 1, maxLength: 256 },
minItems: 1,
maxItems: 10000,
},
},
},
}
export async function cisesRoutes(app: FastifyInstance): Promise<void> {
app.post<{ Body: CheckCodesRequest }>('/api/check-codes/public', async (request) => {
app.post<{ Body: CheckCodesRequest }>('/api/check-codes/public', { schema: checkCodesSchema }, async (request) => {
return checkCodesPublic(request.body)
})
app.post<{ Body: CheckCodesRequest }>('/api/check-codes/auth', async (request) => {
return checkCodesAuth(request.body)
app.post<{ Body: CheckCodesRequest }>('/api/check-codes/auth', { schema: checkCodesSchema }, async (request, reply) => {
try {
return await checkCodesAuth(request.body)
} catch (err) {
if (err instanceof AppError) {
return reply.status(err.statusCode).send({ error: err.message })
}
throw err
}
})
}