mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-11 13:24:55 +01:00
fix: address artifact review feedback
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
b634864c00
commit
cd9e64c2e8
4 files changed
+20
-56
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { buffer } from "node:stream/consumers";
|
||||
import { and, desc, eq, isNotNull, isNull, or, sql, type SQL } from "drizzle-orm";
|
||||
import { and, desc, eq, isNotNull, isNull, notInArray, or, sql, type SQL } from "drizzle-orm";
|
||||
import { alias } from "drizzle-orm/pg-core";
|
||||
import type { Db } from "@paperclipai/db";
|
||||
import {
|
||||
@@ -18,8 +18,7 @@ import {
|
||||
attachmentArtifactWorkProductMetadataSchema,
|
||||
COMPANY_ARTIFACTS_MAX_LIMIT,
|
||||
companyArtifactsQuerySchema,
|
||||
ISSUE_CONTINUATION_SUMMARY_DOCUMENT_KEY,
|
||||
isSystemIssueDocumentKey,
|
||||
SYSTEM_ISSUE_DOCUMENT_KEYS,
|
||||
type CompanyArtifact,
|
||||
type CompanyArtifactMediaKind,
|
||||
type CompanyArtifactsQuery,
|
||||
@@ -161,7 +160,7 @@ export function companyArtifactsService(db: Db, storage?: StorageService) {
|
||||
const documentConditions: SQL[] = [
|
||||
eq(documents.companyId, companyId),
|
||||
or(isNotNull(documents.createdByAgentId), isNotNull(documents.updatedByAgentId))!,
|
||||
sql`${issueDocuments.key} != ${ISSUE_CONTINUATION_SUMMARY_DOCUMENT_KEY}`,
|
||||
notInArray(issueDocuments.key, SYSTEM_ISSUE_DOCUMENT_KEYS),
|
||||
];
|
||||
const documentCursor = cursorCondition(sql<Date>`${documents.updatedAt}`, documentArtifactId, cursor);
|
||||
if (documentCursor) documentConditions.push(documentCursor);
|
||||
@@ -202,7 +201,6 @@ export function companyArtifactsService(db: Db, storage?: StorageService) {
|
||||
.limit(fetchLimit);
|
||||
|
||||
for (const row of documentRows) {
|
||||
if (isSystemIssueDocumentKey(row.key)) continue;
|
||||
const identifier = row.issueIdentifier ?? row.issueId;
|
||||
artifacts.push({
|
||||
id: row.artifactId,
|
||||
|
||||
@@ -324,7 +324,7 @@ function artifactResult(artifact: CompanyArtifact, normalizedQuery: string, toke
|
||||
return {
|
||||
id: artifact.id,
|
||||
type: "artifact",
|
||||
score: score + 120,
|
||||
score,
|
||||
title: artifact.title,
|
||||
href: artifact.href,
|
||||
matchedFields: ["artifact"],
|
||||
|
||||
+15
-49
@@ -1,4 +1,16 @@
|
||||
import { api } from "./client";
|
||||
import type {
|
||||
CompanyArtifact,
|
||||
CompanyArtifactMediaKind,
|
||||
CompanyArtifactsResponse,
|
||||
} from "@paperclipai/shared";
|
||||
|
||||
export type {
|
||||
CompanyArtifact,
|
||||
CompanyArtifactMediaKind as ArtifactMediaKind,
|
||||
CompanyArtifactsResponse,
|
||||
CompanyArtifactSource as ArtifactSource,
|
||||
} from "@paperclipai/shared";
|
||||
|
||||
/**
|
||||
* Company-level Artifacts client (PAP-10359).
|
||||
@@ -10,57 +22,11 @@ import { api } from "./client";
|
||||
* card-ready list so the UI never has to stitch issue-specific endpoints
|
||||
* together.
|
||||
*
|
||||
* The `CompanyArtifact` shape below is the shared contract from the plan. The
|
||||
* backend projection task (PAP-10358) is expected to expose the same fields
|
||||
* (and may also publish them through `@paperclipai/shared`); keeping a local
|
||||
* definition lets the frontend build and test against the contract
|
||||
* independently.
|
||||
* The `CompanyArtifact` shape is imported from `@paperclipai/shared` so the
|
||||
* frontend and server stay synchronized as the contract evolves.
|
||||
*/
|
||||
|
||||
export type ArtifactSource = "document" | "attachment" | "work_product";
|
||||
|
||||
export type ArtifactMediaKind = "image" | "video" | "text" | "document" | "file" | "empty";
|
||||
|
||||
export interface CompanyArtifactIssue {
|
||||
id: string;
|
||||
identifier: string;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export interface CompanyArtifactProject {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CompanyArtifactAgent {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CompanyArtifact {
|
||||
id: string;
|
||||
source: ArtifactSource;
|
||||
mediaKind: ArtifactMediaKind;
|
||||
title: string;
|
||||
previewText: string | null;
|
||||
contentType: string | null;
|
||||
contentPath: string | null;
|
||||
openPath: string | null;
|
||||
downloadPath: string | null;
|
||||
issue: CompanyArtifactIssue;
|
||||
project: CompanyArtifactProject | null;
|
||||
createdByAgent: CompanyArtifactAgent | null;
|
||||
updatedAt: string;
|
||||
/** Board-relative or prefixed link to the artifact inside its issue context. */
|
||||
href: string;
|
||||
}
|
||||
|
||||
export interface CompanyArtifactsResponse {
|
||||
artifacts: CompanyArtifact[];
|
||||
nextCursor: string | null;
|
||||
}
|
||||
|
||||
export type ArtifactKindFilter = ArtifactMediaKind | "all";
|
||||
export type ArtifactKindFilter = Exclude<CompanyArtifactMediaKind, "empty"> | "all";
|
||||
|
||||
export interface ListArtifactsParams {
|
||||
kind?: ArtifactKindFilter;
|
||||
|
||||
@@ -2894,7 +2894,7 @@ export function IssueDetail() {
|
||||
}
|
||||
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
element.classList.add("ring-2", "ring-primary/50", "transition-shadow");
|
||||
timer = setTimeout(() => element.classList.remove("ring-2", "ring-primary/50"), 3000);
|
||||
timer = setTimeout(() => element.classList.remove("ring-2", "ring-primary/50", "transition-shadow"), 3000);
|
||||
};
|
||||
tryScroll();
|
||||
return () => {
|
||||
|
||||
Reference in new issue
Block a user