From 0385f529989bbf560deb7183296fb01291d4e970 Mon Sep 17 00:00:00 2001 From: JohnDoe6345789 Date: Fri, 26 Dec 2025 01:25:31 +0000 Subject: [PATCH] code: route,nextjs,frontends (3 files) --- .../src/entities/session/create_session.hpp | 25 +++++++++++-------- .../src/app/api/levels/metrics/route.test.tsx | 14 +++++++++++ .../src/app/api/levels/metrics/route.ts | 17 +++++++++++++ 3 files changed, 45 insertions(+), 11 deletions(-) create mode 100644 frontends/nextjs/src/app/api/levels/metrics/route.test.tsx create mode 100644 frontends/nextjs/src/app/api/levels/metrics/route.ts diff --git a/dbal/cpp/src/entities/session/create_session.hpp b/dbal/cpp/src/entities/session/create_session.hpp index 773147efd..6d0a1ea6f 100644 --- a/dbal/cpp/src/entities/session/create_session.hpp +++ b/dbal/cpp/src/entities/session/create_session.hpp @@ -18,27 +18,30 @@ namespace session { */ inline Result create(InMemoryStore& store, const CreateSessionInput& input) { if (input.user_id.empty()) { - return Error::validationError("User ID is required"); + return Error::validationError("user_id is required"); } + if (input.token.empty()) { + return Error::validationError("token is required"); + } + if (store.users.find(input.user_id) == store.users.end()) { - return Error::notFound("User not found: " + input.user_id); + return Error::validationError("User not found: " + input.user_id); } - if (input.ttl_seconds <= 0) { - return Error::validationError("TTL must be positive"); + if (store.session_tokens.find(input.token) != store.session_tokens.end()) { + return Error::conflict("Session token already exists: " + input.token); } - + Session session; session.id = store.generateId("session", ++store.session_counter); session.user_id = input.user_id; - session.token = store.generateToken(); - session.expires_at = std::chrono::system_clock::now() + std::chrono::seconds(input.ttl_seconds); - session.ip_address = input.ip_address; - session.user_agent = input.user_agent; + session.token = input.token; + session.expires_at = input.expires_at; session.created_at = std::chrono::system_clock::now(); - + session.last_activity = session.created_at; + store.sessions[session.id] = session; store.session_tokens[session.token] = session.id; - + return Result(session); } diff --git a/frontends/nextjs/src/app/api/levels/metrics/route.test.tsx b/frontends/nextjs/src/app/api/levels/metrics/route.test.tsx new file mode 100644 index 000000000..c41d625e1 --- /dev/null +++ b/frontends/nextjs/src/app/api/levels/metrics/route.test.tsx @@ -0,0 +1,14 @@ +import { describe, expect, it } from 'vitest' + +import { GET } from './route' + +describe('GET /api/levels/metrics', () => { + it('returns a summary for every permission level', async () => { + const response = await GET(new Request('http://example.com/api/levels/metrics')) + const payload = await response.json() + + expect(payload.totalLevels).toBeGreaterThan(0) + expect(Array.isArray(payload.summary)).toBe(true) + expect(payload.summary.every((entry: any) => typeof entry.capabilityCount === 'number')).toBe(true) + }) +}) diff --git a/frontends/nextjs/src/app/api/levels/metrics/route.ts b/frontends/nextjs/src/app/api/levels/metrics/route.ts new file mode 100644 index 000000000..514f9aee5 --- /dev/null +++ b/frontends/nextjs/src/app/api/levels/metrics/route.ts @@ -0,0 +1,17 @@ +import { NextResponse } from 'next/server' + +import { PERMISSION_LEVELS } from '@/app/levels/levels-data' + +export async function GET() { + const summary = PERMISSION_LEVELS.map((level) => ({ + key: level.key, + title: level.title, + capabilityCount: level.capabilities.length, + taglineLength: level.tagline.length, + })) + + return NextResponse.json({ + totalLevels: PERMISSION_LEVELS.length, + summary, + }) +}