/** * Dev-only sample data for the mock base query (see `mock-base-query.ts`). * * Throwaway preview fixtures — realistic enough to demo the four portal * feature areas (vessel registration, seafarer registration, CoC * certificates, exams) without a live backend. Not used unless * `VITE_USE_MOCKS=true`. */ // ------------------------------------------------------------------ profile export const mockPermissions: string[] = [ 'can:View:own-profile', 'can:edit:own-profile', 'can:resubmit:license-application', 'can:upload:own-documents', 'can:View:own-documents', 'can:replace:own-documents', 'can:initiate:own-payment', 'can:View:own-payments', 'can:View:own-notifications', 'can:apply:seafarer-registration', 'can:add:own-sea-service', 'can:edit:own-sea-service', 'can:View:own-sea-service', 'can:upload:own-medical-certificate', 'can:View:own-medical-certificate', 'can:apply:seafarer-certificate', 'can:apply:exam', 'can:View:own-exam', 'can:View:own-certificates', 'can:apply:vessel-registration', 'can:View:own-vessels', 'can:report:own-vessel-incident', 'can:create:license-application', 'can:View:my-license-applications', 'can:update:license-application', 'can:submit:license-application', ]; export const mockProfile = { id: 'profile-mock-001', userId: 'user-mock-001', professionId: 'profession-mock-001', addressId: 'address-mock-001', type: 'INDIVIDUAL', firstName: 'Abebe', middleName: 'Kebede', lastName: 'Tesfaye', gender: 'MALE', dob: '1990-04-12', pob: 'Addis Ababa', maritalStatus: 'MARRIED', isComplete: true, seafarerNumber: 'ET-SF-2026-00147', seafarerStatus: 'ACTIVE', seafarerDepartment: 'DECK', seafarerStatusReason: null, user: { id: 'user-mock-001', email: 'abebe.tesfaye@example.et', username: 'abebe.tesfaye', phoneNumber: '+251911223344', name: { am: 'አበበ ተስፋዬ', en: 'Abebe Tesfaye' }, status: 'ACTIVE', sharepointId: null, hasSetPassword: true, hasFinishedRegistration: true, hasFinishedDMSOnboarding: true, isPhoneNumberVerified: true, userType: 'PORTAL', }, address: { id: 'address-mock-001', idType: 'NID', idNumber: '1234567890123', nationality: 'Ethiopia', regionId: 'region-addis', cityId: 'city-addis', subCityId: 'subcity-bole', woredaId: 'woreda-03', kebeleId: null, streetAddress: 'Bole Road', houseNumber: '14', primaryPhoneNumber: '+251911223344', secondaryPhoneNumber: null, email: 'abebe.tesfaye@example.et', website: null, postalAddress: null, emergencyContactName: 'Selamawit Tesfaye', emergencyContactPhone: '+251911998877', emergencyContactRelation: 'Spouse', isActive: true, }, profession: { id: 'profession-mock-001', departmentId: 'department-deck', name: { en: 'Deck Officer' }, description: { en: 'Deck department officer' }, isActive: true, }, }; export const mockProfileMeResponse = { profile: mockProfile, completeness: 100, missing: [] as string[], permissions: mockPermissions, }; // ------------------------------------------------------------------ vessels export const mockVessels = [ { id: 'vessel-mock-001', registrationNumber: 'ET-VES-2025-000041', name: 'MV Abay Queen', category: 'INLAND_WATERWAY', vesselType: 'Passenger Ferry', imoNumber: '9876543', hullNumber: 'HN-4471', flagState: 'Ethiopia', portOfRegistry: 'Bahir Dar', grossTonnage: 420, passengerCapacity: 120, lengthMeters: 38.5, yearBuilt: 2018, engineType: 'Diesel', enginePowerKw: 950, numberOfEngines: 2, hullMaterial: 'Steel', ownerUserId: 'user-mock-001', ownerProfileId: 'profile-mock-001', ownerName: 'Abebe Tesfaye', applicationId: 'app-vessel-approved-001', licenseId: 'license-vessel-001', status: 'REGISTERED', statusReason: null, statusChangedAt: null, registeredAt: '2025-11-03T09:00:00.000Z', }, { id: 'vessel-mock-002', registrationNumber: 'ET-VES-2024-000019', name: 'MV Tana Star', category: 'INLAND_WATERWAY', vesselType: 'Cargo Vessel', imoNumber: '9765432', hullNumber: 'HN-2290', flagState: 'Ethiopia', portOfRegistry: 'Bahir Dar', grossTonnage: 610, passengerCapacity: null, lengthMeters: 45.2, yearBuilt: 2015, engineType: 'Diesel', enginePowerKw: 1200, numberOfEngines: 2, hullMaterial: 'Steel', ownerUserId: 'user-mock-001', ownerProfileId: 'profile-mock-001', ownerName: 'Abebe Tesfaye', applicationId: 'app-vessel-approved-002', licenseId: 'license-vessel-002', status: 'REGISTERED', statusReason: null, statusChangedAt: null, registeredAt: '2024-06-18T09:00:00.000Z', }, ]; // -------------------------------------------------------------- applications const nowIso = () => new Date().toISOString(); export const mockApplications: Record = { 'app-vessel-approved-001': { id: 'app-vessel-approved-001', applicationNumber: 'VES-2025-000041', licenseTypeId: 'license-type-vessel-registration', licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } }, applicantUserId: 'user-mock-001', kind: 'NEW', status: 'CERTIFICATE_ISSUED', assignedOfficerId: null, claimedAt: null, formData: { vesselDetails: { vesselName: 'MV Abay Queen' } }, companyName: null, tradeName: null, tinNumber: null, businessAddress: null, capitalAmountDeclared: null, capitalAmountVerified: null, adjustmentRound: 0, submittedAt: '2025-10-20T08:00:00.000Z', decidedAt: '2025-11-03T09:00:00.000Z', rejectionReason: null, feeAmount: '3500', feeCurrency: 'ETB', issuedLicenseId: 'license-vessel-001', createdAt: '2025-10-15T08:00:00.000Z', }, 'app-vessel-approved-002': { id: 'app-vessel-approved-002', applicationNumber: 'VES-2024-000019', licenseTypeId: 'license-type-vessel-registration', licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } }, applicantUserId: 'user-mock-001', kind: 'NEW', status: 'CERTIFICATE_ISSUED', assignedOfficerId: null, claimedAt: null, formData: { vesselDetails: { vesselName: 'MV Tana Star' } }, companyName: null, tradeName: null, tinNumber: null, businessAddress: null, capitalAmountDeclared: null, capitalAmountVerified: null, adjustmentRound: 0, submittedAt: '2024-06-01T08:00:00.000Z', decidedAt: '2024-06-18T09:00:00.000Z', rejectionReason: null, feeAmount: '3500', feeCurrency: 'ETB', issuedLicenseId: 'license-vessel-002', createdAt: '2024-05-20T08:00:00.000Z', }, 'app-vessel-pending-003': { id: 'app-vessel-pending-003', applicationNumber: 'VES-2026-000123', licenseTypeId: 'license-type-vessel-registration', licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } }, applicantUserId: 'user-mock-001', kind: 'NEW', status: 'UNDER_REVIEW', assignedOfficerId: 'officer-mock-001', claimedAt: '2026-08-10T10:00:00.000Z', formData: { vesselDetails: { vesselName: 'MV Zeway Pearl' } }, companyName: null, tradeName: null, tinNumber: null, businessAddress: null, capitalAmountDeclared: null, capitalAmountVerified: null, adjustmentRound: 0, submittedAt: '2026-08-05T08:00:00.000Z', decidedAt: null, rejectionReason: null, feeAmount: '3500', feeCurrency: 'ETB', issuedLicenseId: null, createdAt: '2026-08-01T08:00:00.000Z', }, 'app-vessel-resubmit-004': { id: 'app-vessel-resubmit-004', applicationNumber: 'VES-2026-000098', licenseTypeId: 'license-type-vessel-registration', licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } }, applicantUserId: 'user-mock-001', kind: 'NEW', status: 'RESUBMIT_REQUIRED', assignedOfficerId: 'officer-mock-001', claimedAt: '2026-07-20T10:00:00.000Z', formData: { vesselDetails: { vesselName: 'MV Koka Voyager' } }, companyName: null, tradeName: null, tinNumber: null, businessAddress: null, capitalAmountDeclared: null, capitalAmountVerified: null, adjustmentRound: 1, submittedAt: '2026-07-15T08:00:00.000Z', decidedAt: null, rejectionReason: null, feeAmount: '3500', feeCurrency: 'ETB', issuedLicenseId: null, createdAt: '2026-07-10T08:00:00.000Z', }, 'app-seafarer-registered-005': { id: 'app-seafarer-registered-005', applicationNumber: 'SEA-2025-000512', licenseTypeId: 'license-type-seafarer-registration', licenseType: { id: 'license-type-seafarer-registration', key: 'SEAFARER_REGISTRATION', name: { en: 'Seafarer Registration' } }, applicantUserId: 'user-mock-001', kind: 'NEW', status: 'COMPLETED', assignedOfficerId: null, claimedAt: null, formData: { account: { applicantName: 'Abebe Tesfaye' } }, companyName: null, tradeName: null, tinNumber: null, businessAddress: null, capitalAmountDeclared: null, capitalAmountVerified: null, adjustmentRound: 0, submittedAt: '2025-09-01T08:00:00.000Z', decidedAt: '2025-09-20T08:00:00.000Z', rejectionReason: null, feeAmount: '500', feeCurrency: 'ETB', issuedLicenseId: null, createdAt: '2025-08-25T08:00:00.000Z', }, 'app-coc-issued-006': { id: 'app-coc-issued-006', applicationNumber: 'COC-2025-000321', licenseTypeId: 'license-type-coc', licenseType: { id: 'license-type-coc', key: 'CERTIFICATE_OF_COMPETENCY', name: { en: 'Certificate of Competency' } }, applicantUserId: 'user-mock-001', kind: 'NEW', status: 'CERTIFICATE_ISSUED', assignedOfficerId: null, claimedAt: null, formData: { account: { applicantName: 'Abebe Tesfaye' } }, companyName: null, tradeName: null, tinNumber: null, businessAddress: null, capitalAmountDeclared: null, capitalAmountVerified: null, adjustmentRound: 0, submittedAt: '2025-12-01T08:00:00.000Z', decidedAt: '2026-01-10T08:00:00.000Z', rejectionReason: null, feeAmount: '1200', feeCurrency: 'ETB', issuedLicenseId: 'license-coc-001', createdAt: '2025-11-20T08:00:00.000Z', }, 'app-coc-review-007': { id: 'app-coc-review-007', applicationNumber: 'COC-2026-000045', licenseTypeId: 'license-type-coc', licenseType: { id: 'license-type-coc', key: 'CERTIFICATE_OF_COMPETENCY', name: { en: 'Certificate of Competency' } }, applicantUserId: 'user-mock-001', kind: 'RENEWAL', status: 'ELIGIBILITY_APPROVED', assignedOfficerId: 'officer-mock-002', claimedAt: '2026-08-01T10:00:00.000Z', formData: { account: { applicantName: 'Abebe Tesfaye' } }, companyName: null, tradeName: null, tinNumber: null, businessAddress: null, capitalAmountDeclared: null, capitalAmountVerified: null, adjustmentRound: 0, submittedAt: '2026-07-28T08:00:00.000Z', decidedAt: null, rejectionReason: null, feeAmount: '1200', feeCurrency: 'ETB', issuedLicenseId: null, createdAt: '2026-07-25T08:00:00.000Z', }, }; export const mockApplicationDetails: Record = Object.fromEntries( Object.entries(mockApplications).map(([id, application]) => [ id, { application, staff: [], attachments: [], history: [ { id: `hist-${id}-1`, fromStatus: null, toStatus: 'DRAFT', event: 'created', actorUserId: 'user-mock-001', actorName: 'Abebe Tesfaye', actorRole: 'APPLICANT', remark: null, metadata: null, createdAt: application.createdAt, }, { id: `hist-${id}-2`, fromStatus: 'DRAFT', toStatus: 'SUBMITTED', event: 'submitted', actorUserId: 'user-mock-001', actorName: 'Abebe Tesfaye', actorRole: 'APPLICANT', remark: null, metadata: null, createdAt: application.submittedAt ?? application.createdAt, }, ], remarks: application.status === 'RESUBMIT_REQUIRED' ? [ { id: `remark-${id}-1`, roundNumber: 1, targetType: 'DOCUMENT', targetKey: 'vesselOwnershipProof', remark: 'Ownership document is blurred — please re-upload a clearer scan.', isResolved: false, resolvedAt: null, createdAt: application.submittedAt ?? application.createdAt, }, ] : [], openRemarks: application.status === 'RESUBMIT_REQUIRED' ? [ { id: `remark-${id}-1`, roundNumber: 1, targetType: 'DOCUMENT', targetKey: 'vesselOwnershipProof', remark: 'Ownership document is blurred — please re-upload a clearer scan.', isResolved: false, resolvedAt: null, createdAt: application.submittedAt ?? application.createdAt, }, ] : [], availableEvents: [], }, ]), ); // ----------------------------------------------------------------- licenses export const mockLicenses = [ { id: 'license-vessel-001', certificateNumber: 'ET-VES-CERT-2025-041', licenseTypeId: 'license-type-vessel-registration', licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } }, applicationId: 'app-vessel-approved-001', companyName: null, tinNumber: null, issueDate: '2025-11-03', expiryDate: '2027-11-03', status: 'ACTIVE', daysUntilExpiry: 445, renewable: false, verificationCode: 'VESQR001', certificateFileKey: 'certs/vessel-001.pdf', }, { id: 'license-vessel-002', certificateNumber: 'ET-VES-CERT-2024-019', licenseTypeId: 'license-type-vessel-registration', licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' } }, applicationId: 'app-vessel-approved-002', companyName: null, tinNumber: null, issueDate: '2024-06-18', expiryDate: '2026-06-18', status: 'ACTIVE', daysUntilExpiry: 308, renewable: true, verificationCode: 'VESQR002', certificateFileKey: 'certs/vessel-002.pdf', }, { id: 'license-coc-001', certificateNumber: 'ET-COC-2026-000321', licenseTypeId: 'license-type-coc', licenseType: { id: 'license-type-coc', key: 'CERTIFICATE_OF_COMPETENCY', name: { en: 'Certificate of Competency' } }, applicationId: 'app-coc-issued-006', companyName: null, tinNumber: null, issueDate: '2026-01-10', expiryDate: '2031-01-10', status: 'ACTIVE', daysUntilExpiry: 1610, renewable: false, verificationCode: 'COCQR001', certificateFileKey: 'certs/coc-001.pdf', }, ]; // -------------------------------------------------------------------- exams export const mockOpenExams = [ { id: 'exam-open-001', title: { en: 'Officer of the Watch — Written Examination' }, date: '2026-09-15T09:00:00.000Z', venue: 'EMA Headquarters, Addis Ababa', status: 'OPEN', certification: { name: { en: 'Certificate of Competency (Deck)' } }, }, { id: 'exam-open-002', title: { en: 'Marine Engineering Practical Assessment' }, date: '2026-10-02T09:00:00.000Z', venue: 'Bahir Dar Maritime Training Center', status: 'OPEN', certification: { name: { en: 'Certificate of Competency (Engine)' } }, }, ]; export const mockMyExamRegistrations = [ { id: 'reg-mock-001', admissionNumber: 'ADM-2026-000876', createdAt: '2026-08-01T08:00:00.000Z', kind: 'NEW', attemptNumber: 1, attendanceStatus: 'REGISTERED', exam: mockOpenExams[0], }, ]; export const mockMyExamResults = [ { id: 'result-mock-001', totalScore: 82, status: 'PASSED', publishedAt: '2026-03-20T08:00:00.000Z', remark: { en: 'Strong performance in navigation and safety.' }, exam: { id: 'exam-past-001', title: { en: 'Officer of the Watch — Written Examination' }, date: '2026-03-10T09:00:00.000Z', venue: 'EMA Headquarters, Addis Ababa', status: 'CLOSED', certification: { name: { en: 'Certificate of Competency (Deck)' } }, }, }, ]; export const mockMyExamAppeals: any[] = []; // ------------------------------------------------------------ notifications export const mockNotifications = { count: 2, items: [ { id: 'notif-mock-001', subject: { en: 'Application under review' }, content: { en: 'Your vessel registration VES-2026-000123 is now under review.' }, isSeen: false, itemId: 'app-vessel-pending-003', itemType: 'LicenseApplication', metadata: null, createdAt: '2026-08-05T09:00:00.000Z', }, { id: 'notif-mock-002', subject: { en: 'Corrections requested' }, content: { en: 'Please resubmit documents for VES-2026-000098.' }, isSeen: true, itemId: 'app-vessel-resubmit-004', itemType: 'LicenseApplication', metadata: null, createdAt: '2026-07-21T09:00:00.000Z', }, ], }; // ------------------------------------------------------------ license types export const mockLicenseTypeRequirements: Record = { VESSEL_REGISTRATION: { licenseType: { id: 'license-type-vessel-registration', key: 'VESSEL_REGISTRATION', name: { en: 'Vessel Registration' }, description: { en: 'Register a vessel with the Ethiopian Maritime Authority.' }, category: 'MARITIME_PERSONNEL', certificatePrefix: 'VES', feeNewApplication: 3500, feeRenewal: 2000, feeCurrency: 'ETB', capitalThreshold: null, validityMonths: 24, slaHours: 240, inspectionRequired: true, issuesCertificate: true, renewalEnabled: true, requiresOperatorMode: false, formSchema: { sections: [ { key: 'vesselDetails', title: { en: 'Vessel Details' }, fields: [ { key: 'vesselName', label: { en: 'Vessel Name' }, type: 'TEXT', required: true, sortOrder: 1 }, { key: 'vesselType', label: { en: 'Vessel Type' }, type: 'TEXT', required: true, sortOrder: 2 }, { key: 'grossTonnage', label: { en: 'Gross Tonnage' }, type: 'NUMBER', required: true, sortOrder: 3 }, ], sortOrder: 1, }, { key: 'ownerDetails', title: { en: 'Owner Details' }, fields: [ { key: 'nationality', label: { en: 'Nationality' }, type: 'TEXT', required: true, sortOrder: 1 }, { key: 'idNumber', label: { en: 'National ID (Fayda) Number' }, type: 'TEXT', required: true, sortOrder: 2 }, ], sortOrder: 2, }, ], }, isActive: true, sortOrder: 1, }, applicationKind: 'NEW', fee: 3500, feeCurrency: 'ETB', documentRequirements: [ { id: 'doc-vessel-ownership', key: 'vesselOwnershipProof', name: { en: 'Proof of Ownership' }, applicationKind: 'NEW', mode: 'ALWAYS', allowedMimeTypes: ['application/pdf', 'image/jpeg', 'image/png'], maxSizeMb: 10, requiresValidityDates: false, sortOrder: 1, }, ], staffRoleRequirements: [], }, SEAFARER_REGISTRATION: { licenseType: { id: 'license-type-seafarer-registration', key: 'SEAFARER_REGISTRATION', name: { en: 'Seafarer Registration' }, description: { en: 'Register as a seafarer with the Ethiopian Maritime Authority.' }, category: 'MARITIME_PERSONNEL', certificatePrefix: 'SEA', feeNewApplication: 500, feeRenewal: null, feeCurrency: 'ETB', capitalThreshold: null, validityMonths: 0, slaHours: 120, inspectionRequired: false, issuesCertificate: false, renewalEnabled: false, requiresOperatorMode: false, formSchema: { sections: [ { key: 'personalDetails', title: { en: 'Personal Details' }, fields: [ { key: 'applicantName', label: { en: 'Full Name' }, type: 'TEXT', required: true, sortOrder: 1 }, { key: 'department', label: { en: 'Department' }, type: 'SELECT', required: true, options: [ { value: 'DECK', label: { en: 'Deck' } }, { value: 'ENGINE', label: { en: 'Engine' } }, { value: 'CATERING', label: { en: 'Catering' } }, ], sortOrder: 2 }, ], sortOrder: 1, }, ], }, isActive: true, sortOrder: 2, }, applicationKind: 'NEW', fee: 500, feeCurrency: 'ETB', documentRequirements: [ { id: 'doc-seafarer-photo', key: 'passportPhoto', name: { en: 'Passport-size Photograph' }, applicationKind: 'NEW', mode: 'ALWAYS', allowedMimeTypes: ['image/jpeg', 'image/png'], maxSizeMb: 5, requiresValidityDates: false, sortOrder: 1, }, ], staffRoleRequirements: [], }, CERTIFICATE_OF_COMPETENCY: { licenseType: { id: 'license-type-coc', key: 'CERTIFICATE_OF_COMPETENCY', name: { en: 'Certificate of Competency' }, description: { en: 'Apply for a Certificate of Competency.' }, category: 'MARITIME_PERSONNEL', certificatePrefix: 'COC', feeNewApplication: 1200, feeRenewal: 800, feeCurrency: 'ETB', capitalThreshold: null, validityMonths: 60, slaHours: 168, inspectionRequired: false, issuesCertificate: true, renewalEnabled: true, requiresOperatorMode: false, formSchema: { sections: [ { key: 'applicantDetails', title: { en: 'Applicant Details' }, fields: [ { key: 'applicantName', label: { en: 'Full Name' }, type: 'TEXT', required: true, sortOrder: 1 }, { key: 'rank', label: { en: 'Rank Applied For' }, type: 'TEXT', required: true, sortOrder: 2 }, ], sortOrder: 1, }, ], }, isActive: true, sortOrder: 3, }, applicationKind: 'NEW', fee: 1200, feeCurrency: 'ETB', documentRequirements: [ { id: 'doc-coc-seatime', key: 'seaTimeRecord', name: { en: 'Sea Time Record' }, applicationKind: 'NEW', mode: 'ALWAYS', allowedMimeTypes: ['application/pdf'], maxSizeMb: 10, requiresValidityDates: false, sortOrder: 1, }, ], staffRoleRequirements: [], }, }; export const mockLicenseTypes = Object.values(mockLicenseTypeRequirements).map( (r) => r.licenseType, );