Skip to content

Commit 5e85174

Browse files
sasamukuclaude
andcommitted
♻️(app): Remove artifact read operations and switch to analyzedRequirements
Complete Phase 6.4 of the artifact-to-analyzedRequirements migration: **Deleted:** - useRealtimeArtifact hook (Supabase Realtime subscription) **Modified:** - SessionDetailPage: Remove artifact fetch from database - SessionDetailPageClient: Remove useRealtimeArtifact, fix initial tab selection for analyzedRequirements - Output: Remove artifact/artifactError props - Header: Generate markdown from analyzedRequirements instead of artifactDoc - ArtifactContainer: Simplify to only accept analyzedRequirements - Header.stories: Update to use AnalyzedRequirements format - PublicSessionDetailPage: Remove artifact fetch code **Key improvements:** - Initial tab now correctly shows ARTIFACT when only analyzedRequirements exist - Removes all Supabase Realtime dependencies for requirements - Fully transitions to SSE + checkpointer architecture 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 266f913 commit 5e85174

File tree

8 files changed

+55
-220
lines changed

8 files changed

+55
-220
lines changed

frontend/apps/app/components/PublicSessionDetailPage/PublicSessionDetailPage.tsx

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { type Artifact, artifactSchema } from '@liam-hq/artifact'
21
import { schemaSchema } from '@liam-hq/schema'
32
import { notFound } from 'next/navigation'
43
import type { ReactElement } from 'react'
@@ -89,22 +88,6 @@ export const PublicSessionDetailPage = async ({
8988
currentVersionId: latestVersion.id,
9089
})) ?? initialSchema
9190

92-
const { data: artifactData, error } = await supabase
93-
.from('artifacts') // Explicitly specify columns as anon user has grants on individual columns, not all columns
94-
.select('id, design_session_id, artifact, created_at, updated_at')
95-
.eq('design_session_id', designSessionId)
96-
.maybeSingle()
97-
98-
if (error) {
99-
// Degrade gracefully: continue without artifact
100-
// Optionally log error server-side if desired
101-
}
102-
let initialArtifact: Artifact | null = null
103-
const parsedArtifact = safeParse(artifactSchema, artifactData?.artifact)
104-
if (parsedArtifact.success) {
105-
initialArtifact = parsedArtifact.output
106-
}
107-
10891
return (
10992
<PublicLayout>
11093
<ViewModeProvider mode="public">
@@ -135,7 +118,6 @@ export const PublicSessionDetailPage = async ({
135118
}))}
136119
isDeepModelingEnabled={false}
137120
initialIsPublic={true}
138-
initialArtifact={initialArtifact}
139121
senderName="Guest"
140122
/>
141123
</ViewModeProvider>

frontend/apps/app/components/SessionDetailPage/SessionDetailPage.tsx

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ import {
55
getCheckpointErrors,
66
getMessages,
77
} from '@liam-hq/agent'
8-
import {
9-
type AnalyzedRequirements,
10-
type Artifact,
11-
artifactSchema,
12-
} from '@liam-hq/artifact'
8+
import type { AnalyzedRequirements } from '@liam-hq/artifact'
139
import type { Schema } from '@liam-hq/schema'
1410
import { schemaSchema } from '@liam-hq/schema'
1511
import { err, ok, type Result } from 'neverthrow'
@@ -41,7 +37,6 @@ async function loadSessionData(designSessionId: string): Promise<
4137
messages: StoredMessage[]
4238
buildingSchema: NonNullable<Awaited<ReturnType<typeof getBuildingSchema>>>
4339
initialSchema: Schema
44-
initialArtifact: Artifact | null
4540
initialAnalyzedRequirements: AnalyzedRequirements | null
4641
workflowError: string | null
4742
senderName: string
@@ -96,28 +91,10 @@ async function loadSessionData(designSessionId: string): Promise<
9691
return err(new Error('Invalid schema format'))
9792
}
9893

99-
const { data: artifactData, error } = await supabase
100-
.from('artifacts')
101-
// Explicitly specify columns as anon user has grants on individual columns, not all columns
102-
.select('id, design_session_id, artifact, created_at, updated_at')
103-
.eq('design_session_id', designSessionId)
104-
.maybeSingle()
105-
106-
if (error) {
107-
return err(new Error(`Error fetching artifact: ${error.message}`))
108-
}
109-
110-
let initialArtifact: Artifact | null = null
111-
const parsedArtifact = safeParse(artifactSchema, artifactData?.artifact)
112-
if (parsedArtifact.success) {
113-
initialArtifact = parsedArtifact.output
114-
}
115-
11694
return ok({
11795
messages,
11896
buildingSchema,
11997
initialSchema,
120-
initialArtifact,
12198
initialAnalyzedRequirements,
12299
workflowError,
123100
senderName,
@@ -139,7 +116,6 @@ export const SessionDetailPage: FC<Props> = async ({
139116
buildingSchema,
140117
initialSchema,
141118
workflowError,
142-
initialArtifact,
143119
initialAnalyzedRequirements,
144120
senderName,
145121
} = result.value
@@ -167,7 +143,6 @@ export const SessionDetailPage: FC<Props> = async ({
167143
initialDisplayedSchema={initialSchema}
168144
initialPrevSchema={initialPrevSchema}
169145
initialVersions={versions}
170-
initialArtifact={initialArtifact}
171146
isDeepModelingEnabled={isDeepModelingEnabled}
172147
initialIsPublic={initialIsPublic}
173148
initialWorkflowError={workflowError}

frontend/apps/app/components/SessionDetailPage/SessionDetailPageClient.tsx

Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ import {
44
mapStoredMessagesToChatMessages,
55
type StoredMessage,
66
} from '@langchain/core/messages'
7-
import type { AnalyzedRequirements, Artifact } from '@liam-hq/artifact'
7+
import type { AnalyzedRequirements } from '@liam-hq/artifact'
88
import type { Schema } from '@liam-hq/schema'
99
import clsx from 'clsx'
1010
import { type FC, useCallback, useEffect, useRef, useState } from 'react'
1111
import { Chat } from './components/Chat'
1212
import { Output } from './components/Output'
13-
import { useRealtimeArtifact } from './components/Output/components/Artifact/hooks/useRealtimeArtifact'
1413
import { OUTPUT_TABS, type OutputTabValue } from './components/Output/constants'
1514
import { useRealtimeVersionsWithSchema } from './hooks/useRealtimeVersionsWithSchema'
1615
import { useStream } from './hooks/useStream'
@@ -31,29 +30,24 @@ type Props = {
3130
isDeepModelingEnabled: boolean
3231
initialIsPublic: boolean
3332
initialWorkflowError?: string | null
34-
initialArtifact: Artifact | null
3533
senderName: string
3634
}
3735

3836
// Determine the initial active tab based on available data
3937
const determineInitialTab = (
40-
artifact: Artifact | null,
4138
versions: Version[],
39+
analyzedRequirements: AnalyzedRequirements | null,
4240
): OutputTabValue | undefined => {
43-
const hasArtifact = artifact !== null
4441
const hasVersions = versions.length > 0
42+
const hasAnalyzedRequirements = analyzedRequirements !== null
4543

46-
if (!hasArtifact && !hasVersions) {
47-
return undefined
48-
}
49-
50-
// Prioritize ERD tab when versions exist
44+
// Show ERD tab when versions exist
5145
if (hasVersions) {
5246
return OUTPUT_TABS.ERD
5347
}
5448

55-
// Show artifact tab when only artifact exists
56-
if (hasArtifact) {
49+
// Show Artifact tab when only analyzedRequirements exist
50+
if (hasAnalyzedRequirements) {
5751
return OUTPUT_TABS.ARTIFACT
5852
}
5953

@@ -71,11 +65,10 @@ export const SessionDetailPageClient: FC<Props> = ({
7165
isDeepModelingEnabled,
7266
initialIsPublic,
7367
initialWorkflowError,
74-
initialArtifact,
7568
senderName,
7669
}) => {
7770
const [activeTab, setActiveTab] = useState<OutputTabValue | undefined>(
78-
determineInitialTab(initialArtifact, initialVersions),
71+
determineInitialTab(initialVersions, initialAnalyzedRequirements),
7972
)
8073
const [hasReceivedAnalyzedRequirements, setHasReceivedAnalyzedRequirements] =
8174
useState(false)
@@ -106,17 +99,8 @@ export const SessionDetailPageClient: FC<Props> = ({
10699
[setSelectedVersion],
107100
)
108101

109-
const handleArtifactChange = useCallback((newArtifact: unknown) => {
110-
if (newArtifact !== null) {
111-
setActiveTab(OUTPUT_TABS.ARTIFACT)
112-
}
113-
}, [])
114-
115-
const { artifact, error: artifactError } = useRealtimeArtifact({
116-
designSessionId,
117-
initialArtifact,
118-
onChangeArtifact: handleArtifactChange,
119-
})
102+
// Phase 6.4: useRealtimeArtifact and handleArtifactChange removed
103+
// Now using only analyzedRequirements
120104

121105
const chatMessages = mapStoredMessagesToChatMessages(initialMessages)
122106
const { isStreaming, messages, analyzedRequirements, start, replay, error } =
@@ -138,11 +122,9 @@ export const SessionDetailPageClient: FC<Props> = ({
138122
}
139123
}, [analyzedRequirements, hasReceivedAnalyzedRequirements])
140124

125+
// Phase 6.4: artifact removed from condition
141126
const shouldShowOutputSection =
142-
(artifact !== null ||
143-
selectedVersion !== null ||
144-
analyzedRequirements !== null) &&
145-
activeTab
127+
(selectedVersion !== null || analyzedRequirements !== null) && activeTab
146128

147129
// Combine streaming error with workflow errors
148130
const combinedError = error || initialWorkflowError
@@ -221,8 +203,6 @@ export const SessionDetailPageClient: FC<Props> = ({
221203
activeTab={activeTab}
222204
onTabChange={setActiveTab}
223205
initialIsPublic={initialIsPublic}
224-
artifact={artifact}
225-
artifactError={artifactError}
226206
analyzedRequirements={analyzedRequirements}
227207
/>
228208
</div>

frontend/apps/app/components/SessionDetailPage/components/Output/Output.tsx

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
'use client'
22

3-
import type { AnalyzedRequirements, Artifact } from '@liam-hq/artifact'
3+
import type { AnalyzedRequirements } from '@liam-hq/artifact'
44
import type { Schema } from '@liam-hq/schema'
55
import { TabsContent, TabsRoot } from '@liam-hq/ui'
66
import { type ComponentProps, type FC, useCallback, useState } from 'react'
77
import type { ReviewComment } from '../../types'
88
import { ArtifactContainer } from './components/Artifact/ArtifactContainer'
9-
import { formatArtifactToMarkdown } from './components/Artifact/utils'
109
import { ERD } from './components/ERD'
1110
import { Header } from './components/Header'
1211
import type { VersionDropdown } from './components/Header/VersionDropdown'
@@ -26,8 +25,6 @@ type Props = ComponentProps<typeof VersionDropdown> & {
2625
initialIsPublic: boolean
2726
activeTab: OutputTabValue
2827
onTabChange: (value: OutputTabValue) => void
29-
artifact: Artifact | null
30-
artifactError: Error | null
3128
analyzedRequirements?: AnalyzedRequirements | null
3229
}
3330

@@ -39,8 +36,6 @@ export const Output: FC<Props> = ({
3936
activeTab,
4037
onTabChange,
4138
initialIsPublic = false,
42-
artifact,
43-
artifactError,
4439
analyzedRequirements,
4540
...propsForVersionDropdown
4641
}) => {
@@ -71,9 +66,6 @@ export const Output: FC<Props> = ({
7166
}
7267
: handleChangeValue
7368

74-
// Convert artifact data to markdown format
75-
const artifactDoc = artifact ? formatArtifactToMarkdown(artifact) : undefined
76-
7769
return (
7870
<TabsRoot
7971
value={tabValue}
@@ -83,7 +75,7 @@ export const Output: FC<Props> = ({
8375
<Header
8476
schema={schema}
8577
tabValue={tabValue}
86-
artifactDoc={artifactDoc}
78+
analyzedRequirements={analyzedRequirements}
8779
designSessionId={designSessionId}
8880
initialIsPublic={initialIsPublic}
8981
{...propsForVersionDropdown}
@@ -99,11 +91,7 @@ export const Output: FC<Props> = ({
9991
/>
10092
</TabsContent>
10193
<TabsContent value={OUTPUT_TABS.ARTIFACT} className={styles.tabsContent}>
102-
<ArtifactContainer
103-
artifact={artifact}
104-
error={artifactError}
105-
analyzedRequirements={analyzedRequirements}
106-
/>
94+
<ArtifactContainer analyzedRequirements={analyzedRequirements} />
10795
</TabsContent>
10896
</TabsRoot>
10997
)
Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,21 @@
11
'use client'
22

3-
import type {
4-
AnalyzedRequirements,
5-
Artifact as ArtifactType,
6-
} from '@liam-hq/artifact'
3+
import type { AnalyzedRequirements } from '@liam-hq/artifact'
74
import type { FC } from 'react'
85
import { Artifact } from './Artifact'
96
import { formatArtifactToMarkdown } from './utils'
107

118
type Props = {
12-
artifact: ArtifactType | null
13-
error: Error | null
149
analyzedRequirements?: AnalyzedRequirements | null
1510
}
1611

17-
export const ArtifactContainer: FC<Props> = ({
18-
artifact,
19-
error,
20-
analyzedRequirements,
21-
}) => {
22-
const displayData =
23-
analyzedRequirements !== null && analyzedRequirements !== undefined
24-
? { requirement: analyzedRequirements }
25-
: artifact
26-
27-
if (!displayData) {
12+
export const ArtifactContainer: FC<Props> = ({ analyzedRequirements }) => {
13+
if (!analyzedRequirements) {
2814
return <div>No artifact available yet</div>
2915
}
3016

31-
const markdownContent = formatArtifactToMarkdown(displayData)
32-
return <Artifact doc={markdownContent} error={error} />
17+
const markdownContent = formatArtifactToMarkdown({
18+
requirement: analyzedRequirements,
19+
})
20+
return <Artifact doc={markdownContent} error={null} />
3321
}

frontend/apps/app/components/SessionDetailPage/components/Output/components/Artifact/hooks/useRealtimeArtifact.ts

Lines changed: 0 additions & 85 deletions
This file was deleted.

0 commit comments

Comments
 (0)