/ TSKaigi 2026 / 16 / 50
01
C ONCE PT-L EV EL C OMPAR ISON
VALUE
CENTER
ORIGIN
EXAMPLES
Slide 14
Slide 14 text
/ TSKaigi 2026 / 17 / 50
01
C ODE -PAT TE R N CO MPARIS ON
TYPE //
type S =
| {k:'a'}
| {k:'b'};
//
type PropertyId =
Brand;
//
type Out =
z.infer<
typeof schema>;
// →
type BuyerView =
Pick;
PROMPT
Slide 15
Slide 15 text
/ TSKaigi 2026 / 18 / 50
A GEND A
PA R T 0 1
01 PA R T 0 2
02 PA R T 0 3
03 PA R T 0 4
04
Part 02 — 4
Slide 16
Slide 16 text
/ TSKaigi 2026 / 19 / 50
02 C H A P T E R
Slide 17
Slide 17 text
/ TSKaigi 2026 / 20 / 50
02 — 4
01 02 03 04
VALUE
CENTER
ORIGIN
EXAMPLES
Slide 18
Slide 18 text
/ TSKaigi 2026 / 21 / 50
C AT E G O RY
01 / 04
Interaction-centric SaaS
01
02
03
— E X A M P L E S
Slide 19
Slide 19 text
/ TSKaigi 2026 / 22 / 50
01 — S a a S
CL IENT
API
DATA
UI · STATE
Slide 20
Slide 20 text
/ TSKaigi 2026 / 23 / 50
C AT E G O RY
02 / 04
Data-dependent
01
02
03
— E X A M P L E S
Slide 21
Slide 21 text
/ TSKaigi 2026 / 24 / 50
02 —
CL IENT
API
DATA
DATA
Slide 22
Slide 22 text
/ TSKaigi 2026 / 25 / 50
C AT E G O RY
03 / 04
API-centric microservice
01
02
03
— E X A M P L E S
Slide 23
Slide 23 text
/ TSKaigi 2026 / 26 / 50
03 — A PI
CL IENT
API
DATA
API / CONTRACT
Slide 24
Slide 24 text
/ TSKaigi 2026 / 27 / 50
C AT E G O RY
04 / 04
Marketplace
01
02
03
— E X A M P L E S
Slide 25
Slide 25 text
/ TSKaigi 2026 / 28 / 50
04 —
CL IENT
API
DATA
Slide 26
Slide 26 text
/ TSKaigi 2026 / 29 / 50
A GEND A
PA R T 0 1
01 PA R T 0 2
02 PA R T 0 3
03 PA R T 0 4
04
Part 03 — Origin
Slide 27
Slide 27 text
/ TSKaigi 2026 / 30 / 50
03 C H A P T E R
Slide 28
Slide 28 text
/ TSKaigi 2026 / 31 / 50
03
.proto
g R P C
schema.graphql
G r a p h Q L
openapi.yaml
O p e n A P I
schema.prisma
D B S C H E M A
tokens.json
D E S I G N T O K E N S
type / interface
T S
D E S T I N AT I O N
Slide 29
Slide 29 text
/ TSKaigi 2026 / 32 / 50
03 — Orig in
01 02 03 04
ORIGIN
schema.prisma .proto openapi.yaml
HOW
Slide 30
Slide 30 text
/ TSKaigi 2026 / 33 / 50
03 — T S
D E F I N E
TS is the definer ·
01 · INTERACTION
UI
04 · MARKETPLACE
R E C E I V E
TS is the receiver · AI
02 · DATA
DB Schema
03 · API
.proto / OpenAPI
Slide 31
Slide 31 text
/ TSKaigi 2026 / 34 / 50
03 —
01 02 03 04
VALUE
CENTER
ORIGIN
ROLE
EXAMPLES
Slide 32
Slide 32 text
/ TSKaigi 2026 / 35 / 50
03 04
— O P T I O N A — O P T I O N B
.proto schema.prisma openapi.yaml
Slide 33
Slide 33 text
/ TSKaigi 2026 / 36 / 50
A GEND A
PA R T 0 1
01 PA R T 0 2
02 PA R T 0 3
03 PA R T 0 4
04
Part 04 — AI
Slide 34
Slide 34 text
/ TSKaigi 2026 / 37 / 50
04 C H A P T E R
Slide 35
Slide 35 text
/ TSKaigi 2026 / 38 / 50
04 — W ORK FL OW
S T E P 0 1 ·
01
D E FI NE T HE O R IG IN
type FormState =
| { status: 'editing' }
| { status: 'submitting' }
| { status: 'done' };
S T E P 0 2 ·
02
PA SS A S CONT E XT
+ prompt:
S T E P 0 3 · A I
03
GE NER AT E
function Form(...) {
switch (s.status) {
case 'editing': ...
}
}
S T E P 0 4 · Ty p e S c r i p t
04
GU AR D AT C O MPI LE
//
//
//
Slide 36
Slide 36 text
/ TSKaigi 2026 / 39 / 50
04 — P RO M PT DE PT H
L E V E L
01 >
— O U T P U T
L E V E L
02 > type FormState = { ... } +
— O U T P U T
L E V E L
03 > schema.prisma / .proto
— O U T P U T
Slide 37
Slide 37 text
/ TSKaigi 2026 / 40 / 50
04 — C OM P ON EN T TRE E
01
02
03
04
Pick
infer type interface
B A C K E N D
F R O N T E N D
A P I
API B
L 1
Page
L 2
Domain Component
L 4 · D O M A I N - F R E E
Input
L 4 · D O M A I N - F R E E
Button
L 3 Composite UI
A P I ·
API A
Slide 38
Slide 38 text
/ TSKaigi 2026 / 41 / 50
04 — S a a S · 01
invite-member.ts P R O M P T I N P U T
type InviteMemberFormState =
| { status: 'editing'; email: string; role: Role; errors: ValidationError[] }
| { status: 'confirming'; email: string; role: Role }
| { status: 'submitting'; email: string; role: Role }
| { status: 'succeeded'; invitedEmail: string }
| { status: 'failed'; email: string; role: Role; error: SubmitError };
type SubmitError =
| { code: 'already_invited'; existingMemberEmail: string }
| { code: 'quota_exceeded'; currentCount: number; limit: number }
| { code: 'network_error' };
type Role = 'admin' | 'editor' | 'viewer';
Y O U InviteMemberFormState
Slide 39
Slide 39 text
/ TSKaigi 2026 / 42 / 50
04 — S a a S · 02
FailedView.tsx C L A U D E O U T P U T
function FailedView({ error, onRetry, onCancel }: FailedViewProps) {
switch (error.code) {
case 'already_invited':
return
{error.existingMemberEmail}
;
case 'quota_exceeded':
return
( {error.limit} )
( {error.currentCount} )
;
case 'network_error':
return
;
}
// ↑ 'code'
}
O B S E R V E existingMemberEmail limit currentCount
Slide 40
Slide 40 text
/ TSKaigi 2026 / 43 / 50
04 — S a a S · 03
W H AT A I C A N D O W H AT A I C A N N O T D O
Slide 41
Slide 41 text
/ TSKaigi 2026 / 44 / 50
04 — · 0 1
transaction.ts P R O M P T I N P U T
//
type Transaction = {
id: TransactionId;
sellerId: UserId; //
buyerId: UserId; //
price: number;
platformFee: number; //
shippingAddress: Address; //
trackingNumber: string | null;
status: TransactionStatus; // Discriminated Union ( )
// ...
};
Y O U SellerTransactionView BuyerTransactionView
Slide 42
Slide 42 text
/ TSKaigi 2026 / 45 / 50
04 — · 0 2
SellerView.ts S E L L E R
//
type SellerTransactionView = Pick <
Transaction,
| 'id' | 'itemId' | 'buyerId'
| 'price' | 'platformFee'
| 'shippingFee'
| 'trackingNumber'
| 'status' | 'buyerRating'
> & {
netRevenue: number;
};
// : shippingAddress, sellerRating
BuyerView.ts B U Y E R
//
type BuyerTransactionView = Pick <
Transaction,
| 'id' | 'itemId' | 'sellerId'
| 'price' | 'shippingFee'
| 'shippingAddress'
| 'trackingNumber' | 'status'
| 'sellerRating'
> & {
totalPaid: number;
};
// : platformFee, buyerRating
Slide 43
Slide 43 text
/ TSKaigi 2026 / 46 / 50
04 — · 0 3
W H AT A I C A N D O W H AT A I C A N N O T D O
Slide 44
Slide 44 text
/ TSKaigi 2026 / 47 / 50
04 — S UM M ARY
01 · 02 03 04 ·
ORIGIN
HOW
AI · OK
HUMAN · KEEP
Slide 45
Slide 45 text
/ TSKaigi 2026 / 48 / 50
P R I N C I P L E
Slide 46
Slide 46 text
/ TSKaigi 2026 / 49 / 50
RE CAP
01
02
03
Slide 47
Slide 47 text
TSKaigi 2026 · 2026/05/22 50 / 50
F I N
S P E A K E R
omote estie, inc.
F I N D M E
X / @HirokiOmote
S L I D E S W E A R E H I R I N G
estie.jp/careers