refactor!: simplify runtime coordination #7
Backend verify / commits (pull_request) Successful in 29s
Backend verify / security (pull_request) Successful in 8s
Backend verify / verify (pull_request) Failing after 9m36s

Keep financial ownership, atomic publication and refresh CAS.
Failed refresh leaves cookies untouched; logout still clears them.

Remove full-history candle prefetch and special metadata retries.
Use native Pino request context instead of parallel middleware.

BREAKING CHANGE: remove investment stateVersion, queued sync state,
and tbank-sync status progress/resources. Consumers must observe
resources through sync=observe with the updated frontend contract.
This commit is contained in:
2026-10-03 11:38:08 +03:00
parent 0f27da9fd1
commit d698ed9425
48 changed files with 185 additions and 925 deletions
+27 -17
View File
@@ -1,12 +1,13 @@
import { INestApplication } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { Test, TestingModule } from '@nestjs/testing';
import { PinoLogger } from 'nestjs-pino';
import { PARAMS_PROVIDER_TOKEN } from 'nestjs-pino';
import request from 'supertest';
import { App } from 'supertest/types';
import { AppModule } from '../src/app.module';
import { StructuredLogger } from '../src/common/logging/structured-logger.service';
import { loggingOptions } from '../src/common/logging/logging.module';
import { configureApp } from '../src/main';
import { AuthService } from '../src/modules/auth/application/auth.service';
import { PrismaService } from '../src/prisma/prisma.service';
@@ -16,10 +17,22 @@ type Problem = { code: string };
describe('Authentication (e2e)', () => {
let app: INestApplication<App>;
const logs: Record<string, unknown>[] = [];
beforeEach(async () => {
logs.length = 0;
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
}).overrideProvider(PARAMS_PROVIDER_TOKEN).useFactory({
inject: [ConfigService],
factory: (config: Parameters<typeof loggingOptions>[0]) => ({
pinoHttp: {
...loggingOptions(config),
level: 'info',
stream: { write: (line: string) => logs.push(JSON.parse(line) as Record<string, unknown>) },
},
assignResponse: true,
}),
}).compile();
app = moduleFixture.createNestApplication();
@@ -187,10 +200,12 @@ describe('Authentication (e2e)', () => {
]);
const winner = responses.find((response) => response.status === 200);
if (!winner) throw new Error('Expected one successful rotation');
expect(responses.find((response) => response.status === 401)?.headers['set-cookie']).toBeUndefined();
await request(app.getHttpServer())
.post('/api/v1/auth/refresh')
.set('Cookie', cookie)
.expect(401);
.expect(401)
.expect((response) => expect(response.headers['set-cookie']).toBeUndefined());
await request(app.getHttpServer())
.post('/api/v1/auth/refresh')
.set('Cookie', winner.headers['set-cookie'][0])
@@ -304,8 +319,6 @@ describe('Authentication (e2e)', () => {
});
it('exposes a server request ID and logs one completion event', async () => {
const logger = app.get(StructuredLogger);
const event = jest.spyOn(logger, 'event');
const response = await request(app.getHttpServer())
.get('/api/v1/auth/me')
.set('Origin', 'http://localhost:5173')
@@ -315,16 +328,12 @@ describe('Authentication (e2e)', () => {
expect(response.headers['access-control-expose-headers']).toContain(
'X-Request-ID',
);
expect(event).toHaveBeenCalledTimes(1);
expect(event).toHaveBeenCalledWith(
'warn',
'http.request.completed',
expect.objectContaining({ status: 401, code: 'UNAUTHORIZED' }),
);
expect(logs.filter((entry) => entry.requestId === response.headers['x-request-id'])).toEqual([
expect.objectContaining({ level: 40, message: 'http.request.completed', status: 401, code: 'UNAUTHORIZED' }),
]);
});
it('logs an unhandled error with safe public context and correlation', async () => {
const error = jest.spyOn(PinoLogger.prototype, 'error');
const clientRequestId = 'a2dc6fbb-5a48-4c3c-9e3e-4fbf4d638a43';
jest
.spyOn(app.get(AuthService), 'login')
@@ -342,17 +351,18 @@ describe('Authentication (e2e)', () => {
expect(body).toEqual({ status: 500, code: 'INTERNAL_SERVER_ERROR' }),
);
expect(error).toHaveBeenCalledTimes(1);
expect(error).toHaveBeenCalledWith(
const completed = logs.filter((entry) => entry.requestId === response.headers['x-request-id']);
expect(completed).toEqual([
expect.objectContaining({
requestId: response.headers['x-request-id'],
clientRequestId,
status: 500,
code: 'INTERNAL_SERVER_ERROR',
level: 50,
message: 'http.request.completed',
}),
'http.request.completed',
);
expect(JSON.stringify(error.mock.calls)).not.toContain(
]);
expect(JSON.stringify(logs)).not.toContain(
'SYNTHETIC_AUDIT_SECRET',
);
});