mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-16 02:40:39 +09:00
Seed onboarding project and issue goal context
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
parent
59e29afab5
commit
eb73fc747a
8 changed files with 556 additions and 34 deletions
|
|
@ -3,28 +3,54 @@ type MaybeId = string | null | undefined;
|
|||
export function resolveIssueGoalId(input: {
|
||||
projectId: MaybeId;
|
||||
goalId: MaybeId;
|
||||
projectGoalId?: MaybeId;
|
||||
defaultGoalId: MaybeId;
|
||||
}): string | null {
|
||||
if (!input.projectId && !input.goalId) {
|
||||
return input.defaultGoalId ?? null;
|
||||
}
|
||||
return input.goalId ?? null;
|
||||
if (input.goalId) return input.goalId;
|
||||
if (input.projectId) return input.projectGoalId ?? null;
|
||||
return input.defaultGoalId ?? null;
|
||||
}
|
||||
|
||||
export function resolveNextIssueGoalId(input: {
|
||||
currentProjectId: MaybeId;
|
||||
currentGoalId: MaybeId;
|
||||
currentProjectGoalId?: MaybeId;
|
||||
projectId?: MaybeId;
|
||||
goalId?: MaybeId;
|
||||
projectGoalId?: MaybeId;
|
||||
defaultGoalId: MaybeId;
|
||||
}): string | null {
|
||||
const projectId =
|
||||
input.projectId !== undefined ? input.projectId : input.currentProjectId;
|
||||
const goalId =
|
||||
input.goalId !== undefined ? input.goalId : input.currentGoalId;
|
||||
const projectGoalId =
|
||||
input.projectGoalId !== undefined
|
||||
? input.projectGoalId
|
||||
: projectId
|
||||
? input.currentProjectGoalId
|
||||
: null;
|
||||
|
||||
if (!projectId && !goalId) {
|
||||
const resolveFallbackGoalId = (targetProjectId: MaybeId, targetProjectGoalId: MaybeId) => {
|
||||
if (targetProjectId) return targetProjectGoalId ?? null;
|
||||
return input.defaultGoalId ?? null;
|
||||
};
|
||||
|
||||
if (input.goalId !== undefined) {
|
||||
return input.goalId ?? resolveFallbackGoalId(projectId, projectGoalId);
|
||||
}
|
||||
return goalId ?? null;
|
||||
|
||||
const currentFallbackGoalId = resolveFallbackGoalId(
|
||||
input.currentProjectId,
|
||||
input.currentProjectGoalId,
|
||||
);
|
||||
const nextFallbackGoalId = resolveFallbackGoalId(projectId, projectGoalId);
|
||||
|
||||
if (!input.currentGoalId) {
|
||||
return nextFallbackGoalId;
|
||||
}
|
||||
|
||||
if (input.currentGoalId === currentFallbackGoalId) {
|
||||
return nextFallbackGoalId;
|
||||
}
|
||||
|
||||
return input.currentGoalId;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ type IssueUserContextInput = {
|
|||
createdAt: Date | string;
|
||||
updatedAt: Date | string;
|
||||
};
|
||||
type ProjectGoalReader = Pick<Db, "select">;
|
||||
|
||||
function sameRunLock(checkoutRunId: string | null, actorRunId: string | null) {
|
||||
if (actorRunId) return checkoutRunId === actorRunId;
|
||||
|
|
@ -113,6 +114,20 @@ function escapeLikePattern(value: string): string {
|
|||
return value.replace(/[\\%_]/g, "\\$&");
|
||||
}
|
||||
|
||||
async function getProjectDefaultGoalId(
|
||||
db: ProjectGoalReader,
|
||||
companyId: string,
|
||||
projectId: string | null | undefined,
|
||||
) {
|
||||
if (!projectId) return null;
|
||||
const row = await db
|
||||
.select({ goalId: projects.goalId })
|
||||
.from(projects)
|
||||
.where(and(eq(projects.id, projectId), eq(projects.companyId, companyId)))
|
||||
.then((rows) => rows[0] ?? null);
|
||||
return row?.goalId ?? null;
|
||||
}
|
||||
|
||||
function touchedByUserCondition(companyId: string, userId: string) {
|
||||
return sql<boolean>`
|
||||
(
|
||||
|
|
@ -744,6 +759,7 @@ export function issueService(db: Db) {
|
|||
}
|
||||
return db.transaction(async (tx) => {
|
||||
const defaultCompanyGoal = await getDefaultCompanyGoal(tx, companyId);
|
||||
const projectGoalId = await getProjectDefaultGoalId(tx, companyId, issueData.projectId);
|
||||
let executionWorkspaceSettings =
|
||||
(issueData.executionWorkspaceSettings as Record<string, unknown> | null | undefined) ?? null;
|
||||
if (executionWorkspaceSettings == null && issueData.projectId) {
|
||||
|
|
@ -795,6 +811,7 @@ export function issueService(db: Db) {
|
|||
goalId: resolveIssueGoalId({
|
||||
projectId: issueData.projectId,
|
||||
goalId: issueData.goalId,
|
||||
projectGoalId,
|
||||
defaultGoalId: defaultCompanyGoal?.id ?? null,
|
||||
}),
|
||||
...(projectWorkspaceId ? { projectWorkspaceId } : {}),
|
||||
|
|
@ -895,11 +912,21 @@ export function issueService(db: Db) {
|
|||
|
||||
return db.transaction(async (tx) => {
|
||||
const defaultCompanyGoal = await getDefaultCompanyGoal(tx, existing.companyId);
|
||||
const [currentProjectGoalId, nextProjectGoalId] = await Promise.all([
|
||||
getProjectDefaultGoalId(tx, existing.companyId, existing.projectId),
|
||||
getProjectDefaultGoalId(
|
||||
tx,
|
||||
existing.companyId,
|
||||
issueData.projectId !== undefined ? issueData.projectId : existing.projectId,
|
||||
),
|
||||
]);
|
||||
patch.goalId = resolveNextIssueGoalId({
|
||||
currentProjectId: existing.projectId,
|
||||
currentGoalId: existing.goalId,
|
||||
currentProjectGoalId,
|
||||
projectId: issueData.projectId,
|
||||
goalId: issueData.goalId,
|
||||
projectGoalId: nextProjectGoalId,
|
||||
defaultGoalId: defaultCompanyGoal?.id ?? null,
|
||||
});
|
||||
const updated = await tx
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue