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
2 changes: 2 additions & 0 deletions .github/workflows/pull_request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ jobs:
name: Specification drift
- task: check-pack
name: Packaging and type resolution
- task: //#knip
name: Unused code report
steps:
- name: Check out repository
uses: actions/checkout@v6
Expand Down
4 changes: 0 additions & 4 deletions apps/jobnik-manager/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,10 @@
"devDependencies": {
"@faker-js/faker": "^10.5.0",
"@map-colonies/eslint-config": "^9.0.0",
"@map-colonies/infra-copilot-instructions": "^1.2.0",
"@map-colonies/prettier-config": "^1.0.0",
"@map-colonies/tsconfig": "^2.0.0",
"@opentelemetry/sdk-trace-node": "^1.30.1",
"@types/compression": "^1.7.5",
"@types/config": "^3.3.5",
"@types/date-fns": "^2.5.3",
"@types/express": "^4.17.17",
"@types/express-serve-static-core": "^4.19.8",
Expand All @@ -105,11 +103,9 @@
"eslint": "^10.0.0",
"get-port-please": "^3.2.0",
"is-ci": "^4.1.0",
"jest-create-mock-instance": "^2.0.0",
"jest-extended": "^7.0.0",
"jest-openapi": "^0.14.2",
"prettier": "^3.9.5",
"pretty-quick": "^4.1.1",
"prisma": "^6.19.0",
"prisma-json-types-generator": "^3.6.2",
"rimraf": "^6.1.2",
Expand Down
1 change: 0 additions & 1 deletion apps/jobnik-manager/src/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ type SuccessMessagesObj = {
};

export const SERVICE_NAME = readPackageJsonSync().name ?? 'unknown_service';
export const DEFAULT_SERVER_PORT = 80;
export const DB_CONNECTION_TIMEOUT = 20000;
export const TX_TIMEOUT_MS = 30000;
export const NODE_VERSION = process.versions.node;
Expand Down
2 changes: 1 addition & 1 deletion apps/jobnik-manager/src/common/dependencyRegistration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { container as defaultContainer } from 'tsyringe';

type Constructor<T> = new (...args: unknown[]) => T;

export type Providers<T> = ValueProvider<T> | FactoryProvider<T> | ClassProvider<T> | Constructor<T>;
type Providers<T> = ValueProvider<T> | FactoryProvider<T> | ClassProvider<T> | Constructor<T>;

export interface InjectionObject<T> {
token: InjectionToken<T>;
Expand Down
2 changes: 1 addition & 1 deletion apps/jobnik-manager/src/common/errors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { JobOperationStatus, StageOperationStatus, TaskOperationStatus } from '@src/db/prisma/generated/client';
import type { JobOperationStatus, StageOperationStatus, TaskOperationStatus } from '@prismaClient';

export const prismaKnownErrors = {
/**An operation failed because it depends on one or more records that were required but not found. {cause} */
Expand Down
4 changes: 0 additions & 4 deletions apps/jobnik-manager/src/common/interfaces.ts

This file was deleted.

35 changes: 1 addition & 34 deletions apps/jobnik-manager/src/common/semconv.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,15 @@
// OpenTelemetry Messaging Semantic Conventions
// Source: https://opentelemetry.io/docs/specs/semconv/messaging/messaging-spans/
// Only the attributes this service actually sets on spans are kept here.

// Operation name of the messaging operation (e.g., 'send', 'ack', 'nack')
export const ATTR_MESSAGING_OPERATION_NAME = 'messaging.operation.name';
// Messaging system identifier (e.g., 'kafka', 'rabbitmq', 'aws_sqs')
export const ATTR_MESSAGING_SYSTEM = 'messaging.system';
// The type of the messaging operation (e.g., 'create', 'send', 'receive', 'process', 'settle')
export const ATTR_MESSAGING_OPERATION_TYPE = 'messaging.operation.type';
// Unique identifier for the client that consumes or produces a message
export const ATTR_MESSAGING_CLIENT_ID = 'messaging.client.id';
// Name of the consumer group
export const ATTR_MESSAGING_CONSUMER_GROUP_NAME = 'messaging.consumer.group.name';
// Name of the message destination (queue, topic, etc.)
export const ATTR_MESSAGING_DESTINATION_NAME = 'messaging.destination.name';
// Boolean: true if the destination is anonymous (unnamed or auto-generated)
export const ATTR_MESSAGING_DESTINATION_ANONYMOUS = 'messaging.destination.anonymous';
// Boolean: true if the destination is temporary
export const ATTR_MESSAGING_DESTINATION_TEMPORARY = 'messaging.destination.temporary';
// Low-cardinality template for the destination name
export const ATTR_MESSAGING_DESTINATION_TEMPLATE = 'messaging.destination.template';
// Name of the destination subscription (if applicable)
export const ATTR_MESSAGING_DESTINATION_SUBSCRIPTION_NAME = 'messaging.destination.subscription.name';
// Identifier of the partition (if applicable)
export const ATTR_MESSAGING_DESTINATION_PARTITION_ID = 'messaging.destination.partition.id';
// Number of messages in a batch operation
export const ATTR_MESSAGING_BATCH_MESSAGE_COUNT = 'messaging.batch.message_count';
// Message ID (string, unique per message)
export const ATTR_MESSAGING_MESSAGE_ID = 'messaging.message.id';
// Conversation ID (correlation ID)
export const ATTR_MESSAGING_MESSAGE_CONVERSATION_ID = 'messaging.message.conversation_id';
// Size of the message body in bytes
export const ATTR_MESSAGING_MESSAGE_BODY_SIZE = 'messaging.message.body.size';
// Size of the message envelope (body + metadata) in bytes
export const ATTR_MESSAGING_MESSAGE_ENVELOPE_SIZE = 'messaging.message.envelope.size';
// Peer address of the messaging intermediary node
export const ATTR_NETWORK_PEER_ADDRESS = 'network.peer.address';
// Peer port of the messaging intermediary node
export const ATTR_NETWORK_PEER_PORT = 'network.peer.port';
// Server address (domain, IP, or socket)
export const ATTR_SERVER_ADDRESS = 'server.address';
// Server port number
export const ATTR_SERVER_PORT = 'server.port';
// Error type if the messaging operation failed
export const ATTR_ERROR_TYPE = 'error.type';
// Runtime name of the process (e.g., 'nodejs', 'python', 'java')
export const ATTR_PROCESS_RUNTIME_NAME = 'process.runtime.name';
// Runtime version of the process (e.g., 'nodejs 14.17.0')
Expand Down
4 changes: 2 additions & 2 deletions apps/jobnik-manager/src/common/utils/error-express-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { StatusCodes, getReasonPhrase } from 'http-status-codes';
* @property {StatusCodes} [statusCode] - The HTTP status code for the error response
* @property {StatusCodes} [status] - Alternative property for HTTP status code
*/
export interface HttpError extends Error {
interface HttpError extends Error {
statusCode?: StatusCodes;
status?: StatusCodes;
code?: string;
Expand All @@ -20,7 +20,7 @@ export interface HttpError extends Error {
* Represents the structure of the error returned by the middleware.
* stacktrace is only included in the response in development mode.
*/
export interface ErrorResponse {
interface ErrorResponse {
message: string;
stacktrace?: string;
code: string;
Expand Down
4 changes: 2 additions & 2 deletions apps/jobnik-manager/src/common/utils/pagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ interface PaginableDelegate {
count: (args: never) => Prisma.PrismaPromise<number>;
}

export const DEFAULT_PAGE = 1;
export const DEFAULT_PAGE_SIZE = 10;
const DEFAULT_PAGE = 1;
const DEFAULT_PAGE_SIZE = 10;

export interface PaginatedResult<T> {
total: number;
Expand Down
2 changes: 1 addition & 1 deletion apps/jobnik-manager/src/common/utils/promiseTimeout.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export class TimeoutError extends Error {}
class TimeoutError extends Error {}

export const promiseTimeout = async <T>(ms: number, promise: Promise<T>): Promise<T> => {
// Create a promise that rejects in <ms> milliseconds
Expand Down
11 changes: 3 additions & 8 deletions apps/jobnik-manager/src/common/utils/tracingHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { context, propagation } from '@opentelemetry/api';

export const DEFAULT_TRACEPARENT = '00-00000000000000000000000000000000-0000000000000000-00';
export interface Carrier {
interface Carrier {
traceparent?: string;
tracestate?: string;
}

export const DEFAULT_TRACEPARENT = '00-00000000000000000000000000000000-0000000000000000-00';

/**
* Type that ensures traceparent is required and tracestate is nullable
*/
Expand Down Expand Up @@ -44,9 +45,3 @@ export function resolveTraceContext(payload: OptionalTraceContext): ResolvedTrac
tracestate: traceContext.tracestate ?? null,
};
}

/**
* Type helper that transforms a payload with optional trace context into one with required trace context.
* This ensures type safety when passing data to Prisma which requires these fields.
*/
export type WithRequiredTraceContext<T extends OptionalTraceContext> = Omit<T, 'traceparent' | 'tracestate'> & ResolvedTraceContext;
3 changes: 1 addition & 2 deletions apps/jobnik-manager/src/jobs/models/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { Prisma } from '@prismaClient';

type JobModel = components['schemas']['job'];
type JobCreateModel = components['schemas']['createJobPayload'];
type JobGetParams = components['parameters'];
type JobFindCriteriaArg = operations['findJobsV1']['parameters']['query'];
type JobsPaginatedResponse = components['schemas']['jobsPaginatedResponse'];

Expand All @@ -15,4 +14,4 @@ type JobPrismaObject<IncludeStages extends boolean = boolean> = Prisma.JobGetPay
include: { stage: IncludeStages };
}>;

export type { JobModel, JobCreateModel, JobGetParams, JobFindCriteriaArg, JobPrismaObject, JobsPaginatedResponse };
export type { JobModel, JobCreateModel, JobFindCriteriaArg, JobPrismaObject, JobsPaginatedResponse };
2 changes: 0 additions & 2 deletions apps/jobnik-manager/src/stages/models/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,5 +95,3 @@ export {
defaultStatusCounts,
taskOperationStatusWithTotal,
};

export type { StagePersistedSnapshot };
3 changes: 0 additions & 3 deletions apps/jobnik-manager/src/stages/models/models.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import type { Snapshot } from 'xstate';
import type { components, operations } from 'jobnik-openapi';
import type { Prisma, TaskOperationStatus } from '@prismaClient';
import type { JobPrismaObject } from '@src/jobs/models/models';
import type { PrismaTransaction } from '@src/db/types';

type StageModel = components['schemas']['getStageResponse'];
type StageCreateModel = components['schemas']['createStagePayloadRequest'];
type StageCreateBody = StageCreateModel & { jobId: string; xstate: Snapshot<unknown> };
type StageSummary = components['schemas']['summary'];
type StageFindCriteriaArg = operations['getStagesV1']['parameters']['query'];
type StagesPaginatedResponse = components['schemas']['stagesPaginatedResponse'];
Expand Down Expand Up @@ -42,7 +40,6 @@ export type {
StageFindCriteriaArg,
StageCreateModel,
StagePrismaObject,
StageCreateBody,
UpdateSummaryCount,
StageIncludingJob,
StageEntityOptions,
Expand Down
1 change: 0 additions & 1 deletion apps/jobnik-manager/src/tasks/models/taskStateMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,3 @@ function updateTaskMachineState(status: TaskOperationStatus, xstate: PrismaJson.
}

export { taskStateMachine, updateTaskMachineState };
export type { changeStatusOperations };
44 changes: 0 additions & 44 deletions apps/jobnik-manager/tests/configurations/unit/jest.config.js

This file was deleted.

9 changes: 2 additions & 7 deletions apps/jobnik-manager/tests/unit/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,14 @@ failedStageActor.send({ type: 'pend' });
failedStageActor.send({ type: 'process' });
failedStageActor.send({ type: 'fail' });

const waitingStageActor = createActor(stageStateMachine).start();
waitingStageActor.send({ type: 'wait' });

const retriedTaskActor = createActor(taskStateMachine).start();
retriedTaskActor.send({ type: 'pend' });
retriedTaskActor.send({ type: 'process' });
retriedTaskActor.send({ type: 'retry' });

export const jobId = faker.string.uuid();
export const stageId = faker.string.uuid();
export const anotherStageId = faker.string.uuid();
const stageId = faker.string.uuid();

export const jobId = faker.string.uuid();
export const jobEntityWithoutStages = createJobEntity({ id: jobId });
export const stageEntity = createStageEntity({ id: stageId, jobId, data: { name: 'someStage' } });

Expand All @@ -55,7 +51,6 @@ export const inProgressStageXstatePersistentSnapshot = runningStageActor.getPers
export const abortedStageXstatePersistentSnapshot = abortedStageActor.getPersistedSnapshot();
export const pendingStageXstatePersistentSnapshot = pendingStageActor.getPersistedSnapshot();
export const failedStageXstatePersistentSnapshot = failedStageActor.getPersistedSnapshot();
export const waitingStageXstatePersistentSnapshot = waitingStageActor.getPersistedSnapshot();
export const retryTaskXstatePersistentSnapshot = retriedTaskActor.getPersistedSnapshot();
export const completedStageXstatePersistentSnapshot = completedStageActor.getPersistedSnapshot();

Expand Down
7 changes: 0 additions & 7 deletions apps/jobnik-manager/tests/unit/generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import type { Prisma, Stage, Task } from '@prismaClient';
import { JobOperationStatus, Priority, StageOperationStatus, TaskOperationStatus } from '@prismaClient';
import type { findAndLockTask } from '@src/db/prisma/generated/client/sql';
import { jobStateMachine } from '@src/jobs/models/jobStateMachine';
import type { JobCreateModel } from '@src/jobs/models/models';
import { stageStateMachine } from '@src/stages/models/stageStateMachine';
import type { TaskPrismaObject } from '@src/tasks/models/models';
import { taskStateMachine } from '@src/tasks/models/taskStateMachine';
Expand All @@ -22,12 +21,6 @@ export interface StageWithTasks extends Prisma.StageGetPayload<Record<string, un
task?: Task[];
}

export const createJobParams = {
name: 'DEFAULT',
data: { stages: [] },
userMetadata: {},
} satisfies JobCreateModel;

export function createJobEntity(override: Partial<JobWithStages>): JobWithStages {
const jobEntity = {
creationTime: new Date(),
Expand Down
1 change: 0 additions & 1 deletion e2e/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"version": "1.0.0",
"private": true,
"description": "e2e test for the Jobnik platform",
"main": "index.js",
"scripts": {
"e2e": "vitest run",
"e2e:watch": "vitest watch",
Expand Down
26 changes: 25 additions & 1 deletion knip.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,28 @@
{
"$schema": "https://unpkg.com/knip@6/schema.json",
"ignoreDependencies": ["@commitlint/cli", "prettier", "pretty-quick"]
"workspaces": {
"apps/jobnik-manager": {
"entry": ["src/instrumentation.mts"],
"ignore": ["src/db/prisma/generated/**", "src/common/generated/**"],
"ignoreUnresolved": ["./instrumentation.mjs"],
"ignoreDependencies": [
"@map-colonies/prettier-config",
"@types/express-serve-static-core",
"@types/multer",
"@types/swagger-ui-express",
"@prismaClient"
]
},
"packages/jobnik-openapi": {
"ignoreDependencies": ["@map-colonies/prettier-config"]
},
"packages/jobnik-sdk": {
"entry": ["tests/**/*.test-d.ts"],
"ignore": ["src/types/openapi.ts"],
"ignoreDependencies": ["@map-colonies/prettier-config"]
},
"e2e": {
"ignoreDependencies": ["jobnik-manager"]
}
}
}
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"devDependencies": {
"@commitlint/cli": "^21.2.2",
"@commitlint/config-pnpm-scopes": "^21.2.0",
"@commitlint/types": "^21.2.0",
"@map-colonies/commitlint-config": "^2.0.1",
"@map-colonies/prettier-config": "^1.0.0",
"husky": "^9.1.7",
Expand Down
6 changes: 1 addition & 5 deletions packages/jobnik-sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,26 +68,22 @@
"jest-extended": "^6.0.0",
"jobnik-openapi": "workspace:*",
"prettier": "^3.5.3",
"pretty-quick": "^4.1.1",
"prom-client": "^15.1.3",
"publint": "^0.3.24",
"rimraf": "^6.0.1",
"typedoc": "^0.28.12",
"typescript": "^5.8.2",
"vitest": "^4.0.15"
},
"dependencies": {
"@map-colonies/read-pkg": "^2.0.0",
"@map-colonies/semantic-conventions": "^1.0.0",
"@readme/openapi-parser": "^4.0.1",
"date-fns": "^4.1.0",
"http-status-codes": "^2.3.0",
"openapi-fetch": "^0.14.0",
"openapi-types": "^12.1.3",
"openapi-typescript-helpers": "^0.0.15",
"opossum": "^9.0.0",
"undici": "^7.19.1",
"yaml": "^2.8.1"
"undici": "^7.19.1"
},
"peerDependencies": {
"@opentelemetry/api": "^1.9.0",
Expand Down
Loading
Loading