fix(memoro/server): resolve all TypeScript strict mode errors

- Add Hono<{ Variables: AuthVariables }> typing to all authenticated route files
- Conditionally spread optional params to satisfy exactOptionalPropertyTypes
- Fix implicit any on catch handlers (err: unknown)
- Prefix unused _userId param in space service declineInvite
- Remove unused imports (handleTranscriptionCompleted, updateMemoProcessingStatus)
- shared-hono/credits: prefix unused _operation param in validateCredits

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-31 21:59:31 +02:00
parent a02dceb51c
commit 62597707b3
10 changed files with 28 additions and 27 deletions

View file

@ -38,7 +38,7 @@ cleanupRoutes.post('/run', async (c) => {
// POST /manual — manual trigger with optional user IDs
cleanupRoutes.post('/manual', async (c) => {
const body = await c.req.json<{ userIds?: string[] }>().catch(() => ({}));
const body = await c.req.json<{ userIds?: string[] }>().catch(() => ({ userIds: undefined }));
const userIds = body.userIds ?? [];
console.log(

View file

@ -3,10 +3,11 @@
*/
import { Hono } from 'hono';
import type { AuthVariables } from '@manacore/shared-hono';
import { validateCredits, consumeCredits, COSTS } from '../lib/credits';
import { getBalance } from '@manacore/shared-hono';
export const creditRoutes = new Hono();
export const creditRoutes = new Hono<{ Variables: AuthVariables }>();
// GET /pricing — public, returns cost constants
creditRoutes.get('/pricing', (c) => {

View file

@ -6,10 +6,7 @@
import { Hono } from 'hono';
import { HTTPException } from 'hono/http-exception';
import {
handleTranscriptionCompleted,
updateMemoProcessingStatus,
} from '../services/memo';
import { handleTranscriptionCompleted } from '../services/memo';
import { createServiceClient } from '../lib/supabase';
export const internalRoutes = new Hono();
@ -54,11 +51,11 @@ internalRoutes.post('/transcription-completed', async (c) => {
await handleTranscriptionCompleted({
memoId: body.memoId,
userId: body.userId,
transcriptionResult: body.transcriptionResult,
route: body.route,
...(body.transcriptionResult ? { transcriptionResult: body.transcriptionResult } : {}),
...(body.route ? { route: body.route } : {}),
success: body.success,
error: body.error,
fallbackStage: body.fallbackStage,
...(body.error ? { error: body.error } : {}),
...(body.fallbackStage ? { fallbackStage: body.fallbackStage } : {}),
});
return c.json({ success: true, memoId: body.memoId });
} catch (err) {

View file

@ -3,9 +3,10 @@
*/
import { Hono } from 'hono';
import type { AuthVariables } from '@manacore/shared-hono';
import { acceptInvite, declineInvite, getPendingInvites } from '../services/space';
export const inviteRoutes = new Hono();
export const inviteRoutes = new Hono<{ Variables: AuthVariables }>();
// GET /pending — list pending invites for current user
inviteRoutes.get('/pending', async (c) => {

View file

@ -3,10 +3,10 @@
*/
import { Hono } from 'hono';
import type { AuthVariables } from '@manacore/shared-hono';
import { v4 as uuidv4 } from 'uuid';
import {
createMemoFromUploadedFile,
handleTranscriptionCompleted,
callAudioServer,
updateMemoProcessingStatus,
} from '../services/memo';
@ -15,7 +15,7 @@ import { createServiceClient } from '../lib/supabase';
import { validateCredits, consumeCredits, COSTS } from '../lib/credits';
import { generateText } from '../lib/ai';
export const memoRoutes = new Hono();
export const memoRoutes = new Hono<{ Variables: AuthVariables }>();
// POST / — create memo from uploaded file
memoRoutes.post('/', async (c) => {
@ -40,12 +40,12 @@ memoRoutes.post('/', async (c) => {
userId,
filePath: body.filePath,
duration: body.duration,
spaceId: body.spaceId,
blueprintId: body.blueprintId,
memoId: body.memoId,
recordingStartedAt: body.recordingStartedAt,
location: body.location,
mediaType: body.mediaType,
...(body.spaceId ? { spaceId: body.spaceId } : {}),
...(body.blueprintId ? { blueprintId: body.blueprintId } : {}),
...(body.memoId ? { memoId: body.memoId } : {}),
...(body.recordingStartedAt ? { recordingStartedAt: body.recordingStartedAt } : {}),
...(body.location !== undefined ? { location: body.location } : {}),
...(body.mediaType ? { mediaType: body.mediaType } : {}),
});
return c.json(result, 201);
} catch (err) {
@ -122,8 +122,8 @@ memoRoutes.post('/:id/append', async (c) => {
audioPath: body.filePath,
duration: body.duration,
recordingIndex,
recordingLanguages: body.recordingLanguages,
enableDiarization: body.enableDiarization,
...(body.recordingLanguages ? { recordingLanguages: body.recordingLanguages } : {}),
...(body.enableDiarization !== undefined ? { enableDiarization: body.enableDiarization } : {}),
isAppend: true,
}).catch((err) => console.error(`[memos] Append transcription call failed: ${err}`));
});

View file

@ -5,9 +5,10 @@
*/
import { Hono } from 'hono';
import type { AuthVariables } from '@manacore/shared-hono';
import { createServiceClient } from '../lib/supabase';
export const settingsRoutes = new Hono();
export const settingsRoutes = new Hono<{ Variables: AuthVariables }>();
// GET / — get all user settings
settingsRoutes.get('/', async (c) => {

View file

@ -3,6 +3,7 @@
*/
import { Hono } from 'hono';
import type { AuthVariables } from '@manacore/shared-hono';
import { createServiceClient } from '../lib/supabase';
import {
getSpaces,
@ -17,7 +18,7 @@ import {
createInvite,
} from '../services/space';
export const spaceRoutes = new Hono();
export const spaceRoutes = new Hono<{ Variables: AuthVariables }>();
// GET / — list user's spaces
spaceRoutes.get('/', async (c) => {

View file

@ -136,7 +136,7 @@ export async function createMemoFromUploadedFile(params: CreateMemoParams): Prom
userId,
audioPath: filePath,
duration,
blueprintId,
...(blueprintId ? { blueprintId } : {}),
}).catch((err) => {
console.error(`[memo] Audio server call failed for memo ${memoId}:`, err);
updateMemoProcessingStatus(memoId, 'transcription', 'failed', {
@ -208,7 +208,7 @@ export async function handleTranscriptionCompleted(
consumeCredits(userId, 'transcription', cost, `Transcription for memo ${memoId}`, {
memoId,
durationSeconds: duration,
}).catch((err) => console.error('[memo] Failed to consume credits:', err));
}).catch((err: unknown) => console.error('[memo] Failed to consume credits:', err));
// Fire headline generation asynchronously
queueMicrotask(() => {

View file

@ -369,7 +369,7 @@ export async function acceptInvite(
export async function declineInvite(
inviteId: string,
userId: string
_userId: string
): Promise<{ success: boolean }> {
const supabase = createServiceClient();

View file

@ -62,7 +62,7 @@ export async function getBalance(userId: string): Promise<CreditBalance> {
*/
export async function validateCredits(
userId: string,
operation: string,
_operation: string,
amount: number
): Promise<CreditValidationResult> {
try {