feature/api-development #1

Merged
usulpro merged 47 commits from feature/api-development into main 2025-11-29 23:03:01 +07:00
5 changed files with 33 additions and 26 deletions
Showing only changes of commit 0ca1a4576e - Show all commits

View File

@ -117,12 +117,13 @@ export class AliasService {
alias: string,
projectId: string
): Promise<AliasResolution | null> {
// Project aliases can exist on images with or without flowId
// Per spec: images with project alias should be resolvable at project level
const image = await db.query.images.findFirst({
where: and(
eq(images.projectId, projectId),
eq(images.alias, alias),
isNull(images.deletedAt),
isNull(images.flowId)
isNull(images.deletedAt)
),
});

View File

@ -272,6 +272,7 @@ export class ImageService {
projectId: string
): Promise<void> {
// Step 1: Clear alias from any existing image with this alias
// Project aliases can exist on images with or without flowId
await db
.update(images)
.set({
@ -282,8 +283,7 @@ export class ImageService {
and(
eq(images.projectId, projectId),
eq(images.alias, alias),
isNull(images.deletedAt),
isNull(images.flowId)
isNull(images.deletedAt)
)
);

View File

@ -34,19 +34,15 @@ async function main() {
testContext.firstGenId = generation.id;
});
// Test 2: Lazy flow - verify flow doesn't exist yet
// Test 2: Lazy flow - verify flow doesn't exist yet (Section 4.1)
await runTest('Lazy flow - verify flow not created yet', async () => {
try {
await api(`${endpoints.flows}/${testContext.lazyFlowId}`, {
const result = await api(`${endpoints.flows}/${testContext.lazyFlowId}`, {
expectError: true,
});
if (result.status !== 404) {
throw new Error('Flow should not exist yet (lazy creation)');
} catch (error: any) {
if (error.message.includes('should not exist')) {
throw error;
}
log.detail('Flow correctly does not exist', '✓');
}
});
// Test 3: Lazy flow - second use creates flow

View File

@ -91,7 +91,9 @@ async function main() {
}),
});
const result = await api(endpoints.live, {
// Live endpoint requires prompt query parameter
const testPrompt = encodeURIComponent('A simple blue square on white background');
const result = await api(`${endpoints.live}?prompt=${testPrompt}`, {
method: 'GET',
});
@ -117,18 +119,15 @@ async function main() {
method: 'DELETE',
});
// Verify deleted
try {
await api(`${endpoints.live}/scopes/test-scope`, {
// Verify deleted - check for 404 status
const result = await api(`${endpoints.live}/scopes/test-scope`, {
expectError: true,
});
if (result.status !== 404) {
throw new Error('Scope should be deleted');
} catch (error: any) {
if (error.message.includes('should be deleted')) {
throw error;
}
log.detail('Scope deleted', '✓');
}
});
log.section('LIVE URL & SCOPE TESTS COMPLETED');

View File

@ -313,11 +313,22 @@ export async function resolveAlias(
const result = await api(endpoint);
const image = result.data.data;
// Determine scope based on alias type and context
const technicalAliases = ['@last', '@first', '@upload'];
let scope: string;
if (technicalAliases.includes(alias)) {
scope = 'technical';
} else if (flowId) {
scope = 'flow';
} else {
scope = 'project';
}
// Adapt response to match old /resolve/ format for test compatibility
return {
imageId: image.id,
alias: image.alias || alias,
scope: image.flowId ? 'flow' : 'project',
scope,
flowId: image.flowId,
image,
};