Your Power App Is A Lie
Your Power Apps app works perfectly, until one day it fails with no error message and users can only say “it spins.” This podcast explains why low-code apps often break in silence: copy-pasted Power Fx formulas drift into conflicting versions, dev and prod blur without real environments, and hidden dependencies (globals, collections, shadow connectors, personal tokens) quietly decide whether the app runs. The transcript highlights common failure triggers like schema renames, delegation changes that drop records without alerts, throttling that causes duplicate submissions, and chaotic sharing that turns permissions into patches instead of roles.
The solution is a practical refactor path for resilient Microsoft Power Apps development: map every screen, connector, table, and permission; extract and diff formulas to find duplicated logic; define health thresholds (red/yellow/green) for key user paths; add lightweight telemetry; and rehearse failures in test. The “stop the bleed” pattern is using With to enforce local scope, name truth once, avoid global side effects, and build predictable payloads. From there, scale with components, user-defined functions, and solution-based ALM for safer releases.
Your Power App works—until it doesn’t. No error. No warning. Just silence.
Low-code wasn’t sold as “fragile,” but that’s exactly what you get when you copy-paste formulas, skip environments, and bury dependencies where no one can see them. In this episode, we expose why Power Apps fail without telling you, where the fractures hide, and the one local-scope pattern (With) that stops the bleed. By the end, you’ll know how to restructure your screens, components, and ALM so drift disappears and reliability becomes predictable. Section 1 — The Anatomy of Fragility: Why Your App Actually Fails Power Apps don’t break loudly—they degrade quietly. You only notice after users complain, “It just spins.” Common Failure Modes
- Formula Drift: Copy-pasted logic across screens evolves separately and silently diverges.
- No Environment Boundary: Studio “Play” ≠ testing. Dev changes leak into prod instantly.
- Hidden Dependencies: Collections, globals, and shadow connectors impersonating your identity.
- Token Thinking: “It worked once” becomes your QA strategy until a schema rename destroys everything.
- Identity Drift: Permissions become patchwork; app sharing turns into chaos.
- Delegation Traps: Search, In, StartsWith—harmless at 500 rows, catastrophic at 50,000.
- Latency Creep: Dataverse + SharePoint joins push work client-side and burn your performance budget.
- Silent Error Swallowing: Patch failures vanish into thin air; users double-submit and duplicate rows explode.
The Real Pattern Every Power Apps failure is a broken contract:
Screen → Control → Formula → Data → Permission.
When no contract exists, drift fills the vacuum. Section 2 — Forensics: Tracing the Access Paths & Failure Modes You can’t fix an app you can’t see. This section teaches you to run forensic discovery like an engineer—not a guesser. Forensic Steps
- Map critical flows (Submit, Approve, Report).
- Inventory every dependency: tables, connectors, roles, variables, component props.
- Surface invisible state: every Set, UpdateContext, Collect, and App.OnStart cache.
- Diff formulas: normalize and hash to reveal divergence across screens.
- Build the dependency graph: see where trust, data, and identity assumptions connect.
- Rehearse failure: throttle connectors, rename fields, expire tokens, break a flow connection.
- Define your health model: clear red/yellow/green thresholds for your top user paths.
- Instrument telemetry: correlation IDs, durations, outcomes, without PII.
This is where ghosts lose power—because you finally see them. Section 3 — The Fix Starts Local: With() as the Guardrail The turning point.
With() introduces local scope, single truth, named intent, and eliminates formula drift. Why With() Works
- Containment: No global side effects.
- Clarity: Input → Transform → Payload → Output.
- Predictability: One exit path, memoized work, no duplicated logic.
- Performance: Heavy calls cached once, not recalculated per row.
- Safety: Schema coercion and type normalization happen in one place.
Patterns You’ll Learn
- Build query models inside With() blocks
- Construct patch payloads with explicit types
- Route all success/failure through a single result object
- Memoize expensive transforms for stable performance
- Guard inputs to prevent delegation failures
When a screen stabilizes under With(), everything else becomes possible: components, ALM, reuse. Section 4 — Beyond the Screen: Components, UDFs & Enhanced Component Properties Scalability begins when you stop cloning screens and start shipping contracts. Component Rules
- No globals
- Explicit inputs/outputs
- Logic passed through ECP behavior slots
- No hidden connector calls
- No host-assumed variables
- Theme applied through tokens—not hex codes inside controls
UDFs (User Defined Functions) Use them for:
- Model normalization
- Type coercion
- Payload construction
- Telemetry formatting
- Guard checks
Avoid them for:
- Side effects
- Hidden connector calls
- Global state mutation
Together, Components + UDFs give you repeatable, enforceable patterns across apps. Section 5 — Real ALM: Solutions, Branches & Safe Releases This is where hobby apps become software. ALM Requirements
- Solutions-only for Test & Prod
- Three environments: Dev → Test → Prod
- Branches for all changes
- PR reviews with formula diffs, delegation checks, and accessibility lint
- Connection references instead of personal connections
- Environment variables for URLs, endpoints, flags
- Pipelines enforcing import, smoke tests, and approvals
- Rollback paths with versioned managed solutions
Dev is messy. Prod is sacred. Solutions are the boundary. Section 6 — Proof Under Stress: Testing, Monitoring & Controlled Chaos Resilience isn’t proven on happy paths. You’ll Learn to Test
- UDF-level assertions
- Component harness screens
- Synthetic E2E flows
- Token expiry drills
- Schema rename simulations
- Throttling scenarios
- Connectivity chaos
A Power App that survives this will survive in production. Section 7 — The Refactor Plan A practical, step-by-step playbook to stabilize any Power App:
- Inventory screens, variables, connectors
- Identify drift
- Replace global logic with With()
- Extract components
- Introduce UDFs
- Adopt theme tokens
- Move into solutions
- Add pipelines & checks
- Add monitoring & SLOs
- Enforce governance
This plan turns chaos into clarity. Section 8 — Governance Template: Rules That Make Failure Rare Governance isn’t bureaucracy—it’s guardrails that prevent midnight outages. The Rules:
- Naming by scope: app., scn., cmp., fn.
- With() for any formula > 2 lines
- No Set() or globals inside components
- No copy-paste formulas across screens
- Delegation-aware queries only
- Telemetry on all critical paths
- Managed solutions only in Test/Prod
- No personal connections—ever
- PR checklist required for every change
- Monitoring dashboards mandatory
This is how you make failure rare, predictable, and reversible. Conclusion + CTA Your Power App doesn’t fail because it’s low-code; it fails because it’s ungoverned.
Scope your formulas with With(), encapsulate truth into components, move into solutions, and validate everything under stress.
Become a supporter of this podcast: https://www.spreaker.com/podcast/m365-show-podcast--6704921/support.
Follow us on:
LInkedIn
Substack
1
00:00:00,000 --> 00:00:02,600
You see it too, your power app works, until it doesn't.
2
00:00:02,600 --> 00:00:04,500
No error, just silence.
3
00:00:04,500 --> 00:00:07,140
Most power apps are fragile because you copy-paste formulas
4
00:00:07,140 --> 00:00:09,460
built without environments and hide dependencies
5
00:00:09,460 --> 00:00:10,740
where no one will ever find them.
6
00:00:10,740 --> 00:00:13,060
They told you low-code means safe, it doesn't.
7
00:00:13,060 --> 00:00:15,940
It means faster failure if you don't control the access parts.
8
00:00:15,940 --> 00:00:17,020
Here's what actually happens.
9
00:00:17,020 --> 00:00:19,500
We'll expose the fracture points, then we'll refactor the core
10
00:00:19,500 --> 00:00:23,100
with width, components, solution ALM, and real tests
11
00:00:23,100 --> 00:00:24,100
with monitoring.
12
00:00:24,100 --> 00:00:25,940
And there's one pattern that stops the bleed.
13
00:00:25,940 --> 00:00:27,500
It shows up in section three.
14
00:00:27,500 --> 00:00:29,260
You already know why that matters.
15
00:00:29,260 --> 00:00:32,180
The anatomy of fragility, how your app actually fails.
16
00:00:32,180 --> 00:00:35,700
Look at your formulas, not the pretty screen, the text, the mess.
17
00:00:35,700 --> 00:00:38,820
You copy a snippet from screen one, on select to screen three, on select,
18
00:00:38,820 --> 00:00:39,820
then you tweak a filter.
19
00:00:39,820 --> 00:00:42,020
A variable name changes, the payload diverges.
20
00:00:42,020 --> 00:00:44,580
Now you've got two truths, both wrong in different ways.
21
00:00:44,580 --> 00:00:47,300
Duplicated logic breeds drift, drift breeds ghosts.
22
00:00:47,300 --> 00:00:49,020
You're hunting bugs without a map.
23
00:00:49,020 --> 00:00:50,940
And because there's no real environment boundary,
24
00:00:50,940 --> 00:00:53,460
dev bleeds into prod, you press play in studio
25
00:00:53,460 --> 00:00:54,980
and believe that's testing it.
26
00:00:54,980 --> 00:00:55,580
It isn't.
27
00:00:55,580 --> 00:00:59,460
A single schema tweak at noon becomes a production outage at 1201.
28
00:00:59,460 --> 00:01:01,500
No roll back path, no version solution,
29
00:01:01,500 --> 00:01:03,820
just a quiet failure, users can't describe.
30
00:01:03,820 --> 00:01:05,420
It spins.
31
00:01:05,420 --> 00:01:07,580
They're right, it spins because you merged making
32
00:01:07,580 --> 00:01:09,300
and running into the same surface.
33
00:01:09,300 --> 00:01:11,380
Hidden dependencies, the silent killers.
34
00:01:11,380 --> 00:01:14,460
Collections you fill once on app, on start, never refresh,
35
00:01:14,460 --> 00:01:15,540
and assume our truth.
36
00:01:15,540 --> 00:01:19,060
Invisible globals, like set user role, that decide access,
37
00:01:19,060 --> 00:01:20,980
but live nowhere, documented.
38
00:01:20,980 --> 00:01:23,620
Shadow connectors authenticated under your account,
39
00:01:23,620 --> 00:01:24,780
not the app's identity.
40
00:01:24,780 --> 00:01:26,420
You think you're calling dataverse.
41
00:01:26,420 --> 00:01:27,500
You're calling yourself.
42
00:01:27,500 --> 00:01:29,500
When your token expires, the app dies.
43
00:01:29,500 --> 00:01:30,620
Users blame the button.
44
00:01:30,620 --> 00:01:31,660
The button blames you.
45
00:01:31,660 --> 00:01:32,540
Token thinking.
46
00:01:32,540 --> 00:01:35,620
You validate it works with a single happy path click.
47
00:01:35,620 --> 00:01:36,820
The token is green today.
48
00:01:36,820 --> 00:01:37,620
So you ship.
49
00:01:37,620 --> 00:01:39,740
Then a column is renamed from status to state
50
00:01:39,740 --> 00:01:41,740
or a lookup becomes polymorphic.
51
00:01:41,740 --> 00:01:42,620
Delegation shifts.
52
00:01:42,620 --> 00:01:43,900
The blue dot light to you.
53
00:01:43,900 --> 00:01:45,860
A thousand records become 501.
54
00:01:45,860 --> 00:01:46,980
The last one vanishes.
55
00:01:46,980 --> 00:01:48,540
No alert, just missing data.
56
00:01:48,540 --> 00:01:49,220
That's not a bug.
57
00:01:49,220 --> 00:01:50,780
That's a fractured identity drift.
58
00:01:50,780 --> 00:01:52,060
You share the app with a link.
59
00:01:52,060 --> 00:01:53,420
You add one user directly.
60
00:01:53,420 --> 00:01:56,060
Then a group, then another link permissions become patches,
61
00:01:56,060 --> 00:01:56,980
not roles.
62
00:01:56,980 --> 00:01:58,380
Someone can see everything they shouldn't.
63
00:01:58,380 --> 00:02:00,220
Someone else sees nothing and opens a ticket.
64
00:02:00,220 --> 00:02:02,100
You fix it by adding more people.
65
00:02:02,100 --> 00:02:03,780
You're widening the blast radius.
66
00:02:03,780 --> 00:02:04,900
The audit trail is a rumor.
67
00:02:04,900 --> 00:02:06,020
The truth is chaos.
68
00:02:06,020 --> 00:02:07,420
Dataverse meets SharePoint.
69
00:02:07,420 --> 00:02:08,980
Look up hell.
70
00:02:08,980 --> 00:02:10,820
You store choices in SharePoint for speed.
71
00:02:10,820 --> 00:02:12,900
Then you join to dataverse tables in the app.
72
00:02:12,900 --> 00:02:14,300
Delegation breaks on the join.
73
00:02:14,300 --> 00:02:15,820
The formula still returns something.
74
00:02:15,820 --> 00:02:17,100
Enough to fool your eyes.
75
00:02:17,100 --> 00:02:18,940
Meanwhile, the filter flips client side
76
00:02:18,940 --> 00:02:20,700
and costs seconds per interaction.
77
00:02:20,700 --> 00:02:21,900
Multiply by users.
78
00:02:21,900 --> 00:02:22,900
Multiply by clicks.
79
00:02:22,900 --> 00:02:24,700
That's your latency budget burned on a guess.
80
00:02:24,700 --> 00:02:26,740
Delegation traps hide in friendly shapes.
81
00:02:26,740 --> 00:02:28,140
Search starts within.
82
00:02:28,140 --> 00:02:29,260
They look harmless.
83
00:02:29,260 --> 00:02:31,340
Until data grows, then you're paging a gallery
84
00:02:31,340 --> 00:02:32,860
by scrolling, not by design.
85
00:02:32,860 --> 00:02:34,260
You tell yourself it's fine for now
86
00:02:34,260 --> 00:02:37,260
that phrases the root cause in every post-mortem you'll write.
87
00:02:37,260 --> 00:02:38,060
You patch symptoms.
88
00:02:38,060 --> 00:02:41,700
You add if eyes blank, VRX, default VRX in three more places.
89
00:02:41,700 --> 00:02:43,180
You wrap everything in coalesce.
90
00:02:43,180 --> 00:02:44,260
You set another global.
91
00:02:44,260 --> 00:02:45,220
You feel safer.
92
00:02:45,220 --> 00:02:45,740
You're not.
93
00:02:45,740 --> 00:02:47,220
You created more branches to drift.
94
00:02:47,220 --> 00:02:48,340
More state to forget.
95
00:02:48,340 --> 00:02:50,060
More outcomes to test, but you won't,
96
00:02:50,060 --> 00:02:52,420
because there's no harness, no specs, no health model.
97
00:02:52,420 --> 00:02:53,420
Just hope.
98
00:02:53,420 --> 00:02:55,780
The dependency graph exists whether you admitted or not.
99
00:02:55,780 --> 00:02:59,260
Screen, control, formula, data, permission.
100
00:02:59,260 --> 00:03:02,180
Right now it lives only in your head and your head changes jobs.
101
00:03:02,180 --> 00:03:02,860
The app doesn't.
102
00:03:02,860 --> 00:03:05,900
It stays behind brittle, loyal to outdated assumptions.
103
00:03:05,900 --> 00:03:07,980
New makers open it and inherit your ghosts.
104
00:03:07,980 --> 00:03:08,740
They add new ones.
105
00:03:08,740 --> 00:03:11,340
That's how a two week app becomes a two year liability.
106
00:03:11,340 --> 00:03:12,580
Failure rehearses quietly.
107
00:03:12,580 --> 00:03:13,780
You won't notice it first.
108
00:03:13,780 --> 00:03:16,020
Connector throttling returns 4.29 for a minute.
109
00:03:16,020 --> 00:03:17,220
Your code retries never.
110
00:03:17,220 --> 00:03:18,740
Users hit submit twice.
111
00:03:18,740 --> 00:03:19,740
Duplicate rows.
112
00:03:19,740 --> 00:03:21,740
Finance asks why totals don't match.
113
00:03:21,740 --> 00:03:22,580
You blame die-tiverse.
114
00:03:22,580 --> 00:03:23,580
It blames your formula.
115
00:03:23,580 --> 00:03:25,500
Both are right, because you never defined
116
00:03:25,500 --> 00:03:27,860
red, yellow, green for the critical user paths.
117
00:03:27,860 --> 00:03:28,620
No thresholds.
118
00:03:28,620 --> 00:03:29,140
No alerts.
119
00:03:29,140 --> 00:03:30,340
Just vibes.
120
00:03:30,340 --> 00:03:31,500
And then the schema rename.
121
00:03:31,500 --> 00:03:32,860
It's always the schema rename.
122
00:03:32,860 --> 00:03:33,580
The table moves.
123
00:03:33,580 --> 00:03:35,820
The column type shifts from text to choice.
124
00:03:35,820 --> 00:03:37,500
Your patch payload keeps sending text,
125
00:03:37,500 --> 00:03:39,380
power effects coerces until it can't.
126
00:03:39,380 --> 00:03:40,220
One screen errors.
127
00:03:40,220 --> 00:03:40,980
Another swallows it.
128
00:03:40,980 --> 00:03:42,500
The app mostly works.
129
00:03:42,500 --> 00:03:43,180
That word mostly.
130
00:03:43,180 --> 00:03:44,380
That's the lie.
131
00:03:44,380 --> 00:03:45,620
You think this is about features.
132
00:03:45,620 --> 00:03:46,140
It isn't.
133
00:03:46,140 --> 00:03:48,380
It's about control, scope, contracts, boundaries.
134
00:03:48,380 --> 00:03:50,780
Without them, every fix invites a new failure.
135
00:03:50,780 --> 00:03:52,420
That's the pattern you feel it.
136
00:03:52,420 --> 00:03:53,700
But here's where it gets interesting.
137
00:03:53,700 --> 00:03:55,100
You can localize the blast.
138
00:03:55,100 --> 00:03:56,380
You can constrain drift.
139
00:03:56,380 --> 00:03:59,460
You can stop the silence state from leaking across screens.
140
00:03:59,460 --> 00:04:01,060
And you do it by pulling truth closer,
141
00:04:01,060 --> 00:04:03,500
naming it once and refusing global side effects.
142
00:04:03,500 --> 00:04:04,580
You don't need to rewrite.
143
00:04:04,580 --> 00:04:06,620
You need a guardrail, local first, then structure,
144
00:04:06,620 --> 00:04:08,380
then environments, then proof under stress.
145
00:04:08,380 --> 00:04:10,660
You patch symptoms, therefore the chaos grows.
146
00:04:10,660 --> 00:04:11,540
You already knew that.
147
00:04:11,540 --> 00:04:13,020
Now we cut the access parts.
148
00:04:13,020 --> 00:04:16,260
In forensics, and tracing the access parts in failure modes,
149
00:04:16,260 --> 00:04:19,420
now we trace the access parts quietly, methodically.
150
00:04:19,420 --> 00:04:20,460
Start with the map.
151
00:04:20,460 --> 00:04:23,300
Not your memory, a list, submit, approve, report,
152
00:04:23,300 --> 00:04:26,100
three flows, name them, then list every table, connector,
153
00:04:26,100 --> 00:04:27,220
and role they touch.
154
00:04:27,220 --> 00:04:30,420
Issues, approvals, users, attachments, dataverse,
155
00:04:30,420 --> 00:04:33,860
SharePoint, Outlook, a custom connector, you forgot your own.
156
00:04:33,860 --> 00:04:37,020
Roads, maker, user, approver, admin, who actually has what?
157
00:04:37,020 --> 00:04:38,740
Write it, don't trust the SharePain.
158
00:04:38,740 --> 00:04:41,060
It lies through omission, surface the invisible,
159
00:04:41,060 --> 00:04:42,660
enumerate variables.
160
00:04:42,660 --> 00:04:45,260
Every set, every update context, every collect,
161
00:04:45,260 --> 00:04:48,220
every with local, export a screen-by-screen inventory.
162
00:04:48,220 --> 00:04:50,580
Apped on-start, screened on-visible control,
163
00:04:50,580 --> 00:04:53,220
on-select, where is state created, where is it mutated?
164
00:04:53,220 --> 00:04:54,900
Collections that cache tables.
165
00:04:54,900 --> 00:04:58,220
Variables that toggle UI and permissions in the same breath,
166
00:04:58,220 --> 00:05:00,580
component properties that pass data one way and secrets
167
00:05:00,580 --> 00:05:02,540
the other, you need to see the shadow state.
168
00:05:02,540 --> 00:05:04,180
The truth behind the formula bar,
169
00:05:04,180 --> 00:05:06,260
diff the formulas, you think screen one and screen three
170
00:05:06,260 --> 00:05:07,500
share the same filter?
171
00:05:07,500 --> 00:05:09,300
Prove it, extract the text.
172
00:05:09,300 --> 00:05:11,460
Normalize white space, hash each formula,
173
00:05:11,460 --> 00:05:14,580
equal hashes mean one truth, mismatched hashes mean drift.
174
00:05:14,580 --> 00:05:16,980
Now grouped by intent, load issues,
175
00:05:16,980 --> 00:05:20,580
build patch payload, compute can edit, find duplicates,
176
00:05:20,580 --> 00:05:23,580
find variance, keep one, mark the rest for effector,
177
00:05:23,580 --> 00:05:25,220
you can't fix what you can't find,
178
00:05:25,220 --> 00:05:26,820
you can't find what you don't name,
179
00:05:26,820 --> 00:05:29,020
build the dependency graph, screen,
180
00:05:29,020 --> 00:05:31,620
control formula, data, permission, draw edges,
181
00:05:31,620 --> 00:05:33,300
control gallery issues.
182
00:05:33,300 --> 00:05:36,500
Items depends on issues table with a filter using Valleuser.
183
00:05:36,500 --> 00:05:38,540
Valleuser depends on Office 365 users,
184
00:05:38,540 --> 00:05:41,460
my profile V2, that depends on a connector scope to you.
185
00:05:41,460 --> 00:05:42,940
Permission for patch calls a flow,
186
00:05:42,940 --> 00:05:44,460
the flow's connection reference points
187
00:05:44,460 --> 00:05:46,420
to a service principle or not.
188
00:05:46,420 --> 00:05:49,180
Now you see it, not an app, a web of trust assumptions,
189
00:05:49,180 --> 00:05:50,340
any one of them can snap,
190
00:05:50,340 --> 00:05:53,740
rehearse failure, intentionally rename a column in a test clone.
191
00:05:53,740 --> 00:05:55,860
Status, state, watch the blast radius,
192
00:05:55,860 --> 00:05:58,220
throttle a connector to 429 for 60 seconds.
193
00:05:58,220 --> 00:05:59,860
Do users double submit, do you dedube,
194
00:05:59,860 --> 00:06:00,860
or do you pray?
195
00:06:00,860 --> 00:06:02,500
Break off on one connection reference,
196
00:06:02,500 --> 00:06:04,900
does the app fail loud with a banner?
197
00:06:04,900 --> 00:06:06,780
Or silently swallow errors into success,
198
00:06:06,780 --> 00:06:08,380
equals false that no one reads?
199
00:06:08,380 --> 00:06:11,700
Rotate a certificate on a custom connector in test.
200
00:06:11,700 --> 00:06:12,900
Does anything alert?
201
00:06:12,900 --> 00:06:15,300
Or do you discover it after finance emails you?
202
00:06:15,300 --> 00:06:17,500
Define the health model before the next incident
203
00:06:17,500 --> 00:06:18,780
defines it for you.
204
00:06:18,780 --> 00:06:21,020
For each user path, assign red, yellow, green.
205
00:06:21,020 --> 00:06:23,700
Submit path, time to first byte, 500 miss green,
206
00:06:23,700 --> 00:06:27,100
500, 150 miss yellow, 150 miss red, error rate green,
207
00:06:27,100 --> 00:06:29,220
1% yellow, 5% red above that.
208
00:06:29,220 --> 00:06:31,500
Approved path, same discipline, report path,
209
00:06:31,500 --> 00:06:34,260
delegation count, page size, query shape, monitored.
210
00:06:34,260 --> 00:06:36,740
These aren't dashboards, they're contracts with reality.
211
00:06:36,740 --> 00:06:39,140
Instrument the app, minimal, precise,
212
00:06:39,140 --> 00:06:41,940
a single telemetry, UDF, you'll write later.
213
00:06:41,940 --> 00:06:43,820
For now, add a lock call at path start
214
00:06:43,820 --> 00:06:46,380
on failure on success, include correlation ID,
215
00:06:46,380 --> 00:06:49,940
user ID, path name, duration, outcome, no PI, just signals.
216
00:06:49,940 --> 00:06:50,820
You'll hate the noise.
217
00:06:50,820 --> 00:06:53,020
Good, noise means truth surfaced, tune later.
218
00:06:53,020 --> 00:06:54,220
Don't optimize silence.
219
00:06:54,220 --> 00:06:56,340
Now examine identity, the fracture you ignored.
220
00:06:56,340 --> 00:06:57,660
Export the app permissions.
221
00:06:57,660 --> 00:07:00,820
Group based, direct grants, owners who shouldn't be owners.
222
00:07:00,820 --> 00:07:03,140
List makers with environment maker versus basic user,
223
00:07:03,140 --> 00:07:05,180
compared to who can promote solutions.
224
00:07:05,180 --> 00:07:07,060
Miss match equals attack surface.
225
00:07:07,060 --> 00:07:10,540
Shadow logins, flows using your personal connection,
226
00:07:10,540 --> 00:07:12,140
replaced with connection references.
227
00:07:12,140 --> 00:07:13,500
If you can't mark as red,
228
00:07:13,500 --> 00:07:15,660
don't rationalize it data contracts.
229
00:07:15,660 --> 00:07:17,340
Say the quiet part out loud.
230
00:07:17,340 --> 00:07:21,060
For each patch, specify expected schema, field name, type,
231
00:07:21,060 --> 00:07:24,540
required, enum values max links, then validate upstream.
232
00:07:24,540 --> 00:07:26,740
If your payload builder can't prove the shape,
233
00:07:26,740 --> 00:07:28,340
it fails before sending.
234
00:07:28,340 --> 00:07:30,500
Cheap, failure, loud failure.
235
00:07:30,500 --> 00:07:33,540
If you accept polymorphic lookups, record the entity set.
236
00:07:33,540 --> 00:07:36,460
If you accept option sets, store the numeric value,
237
00:07:36,460 --> 00:07:38,780
not the label string you liked last sprint.
238
00:07:38,780 --> 00:07:40,660
You're building a forensic spine?
239
00:07:40,660 --> 00:07:43,140
Sources, state, transformations,
240
00:07:43,140 --> 00:07:45,140
sinks, permissions, health.
241
00:07:45,140 --> 00:07:47,340
Once it exists, ghosts lose power.
242
00:07:47,340 --> 00:07:48,340
They can still haunt.
243
00:07:48,340 --> 00:07:49,300
They just can't hide.
244
00:07:49,300 --> 00:07:51,180
Everything changes when you close the first loop.
245
00:07:51,180 --> 00:07:53,620
You run the schema rename rehearsal, a screen breaks.
246
00:07:53,620 --> 00:07:55,220
You see exactly where you capture it.
247
00:07:55,220 --> 00:07:56,420
You fix the formula once.
248
00:07:56,420 --> 00:07:57,700
But seeing isn't fixing.
249
00:07:57,700 --> 00:07:59,340
You need discipline in the formula surface.
250
00:07:59,340 --> 00:08:01,860
Local scope, named intent, single exits.
251
00:08:01,860 --> 00:08:02,780
You already know the word.
252
00:08:02,780 --> 00:08:04,380
With, we'll use it as the guardrail,
253
00:08:04,380 --> 00:08:05,820
then pull logic into components,
254
00:08:05,820 --> 00:08:08,900
then bind the entire mess into solutions, branches, checks,
255
00:08:08,900 --> 00:08:09,420
and gates.
256
00:08:09,420 --> 00:08:10,780
Because without proof under stress,
257
00:08:10,780 --> 00:08:13,540
you're still guessing and guesses fail in silence.
258
00:08:13,540 --> 00:08:16,940
The fix starts local, with as the guardrail.
259
00:08:16,940 --> 00:08:18,860
With is how you stop the bleed.
260
00:08:18,860 --> 00:08:21,820
Local scope, named intent, one entry, one exit,
261
00:08:21,820 --> 00:08:23,060
no global, no drift.
262
00:08:23,060 --> 00:08:23,780
Here's the pattern.
263
00:08:23,780 --> 00:08:26,380
You take a tangled formula and you pull truth closely.
264
00:08:26,380 --> 00:08:27,100
You name it.
265
00:08:27,100 --> 00:08:28,220
You compute it once.
266
00:08:28,220 --> 00:08:29,540
You reuse it downstream.
267
00:08:29,540 --> 00:08:31,220
Everything inside the block is sealed.
268
00:08:31,220 --> 00:08:32,660
Outside can't mutate it.
269
00:08:32,660 --> 00:08:34,460
That's the guardrail.
270
00:08:34,460 --> 00:08:35,900
Structure it like this.
271
00:08:35,900 --> 00:08:40,620
With, is text, user, var user, now, now.
272
00:08:40,620 --> 00:08:41,740
Input.
273
00:08:41,740 --> 00:08:44,580
This item, source, filter, issues,
274
00:08:44,580 --> 00:08:47,380
status in an open, in progress,
275
00:08:47,380 --> 00:08:52,420
transformed, add columns, source, can edit, user.
276
00:08:52,420 --> 00:08:55,620
Email, L, created by email, patent, approver,
277
00:08:55,620 --> 00:08:57,340
in var user, roles.
278
00:08:57,340 --> 00:09:00,260
Selection, look up, transformed, ID use input,
279
00:09:00,260 --> 00:09:03,500
ID payload, issue selection, ID title, selection,
280
00:09:03,500 --> 00:09:06,300
title, state if selection, can edit in progress,
281
00:09:06,300 --> 00:09:08,340
open, modified on CTX.
282
00:09:08,340 --> 00:09:09,900
Now, turn, send, patch, issues,
283
00:09:09,900 --> 00:09:12,900
look up issues, ID, is payload, issue in payload,
284
00:09:12,900 --> 00:09:16,100
and read it again, input, transform, output,
285
00:09:16,100 --> 00:09:19,620
named steps, predictable shapes, no set, no collect,
286
00:09:19,620 --> 00:09:20,660
no shadow state.
287
00:09:20,660 --> 00:09:23,580
Compose formulas by intent, start the with-with-plane
288
00:09:23,580 --> 00:09:25,500
English labels, input source, transformed,
289
00:09:25,500 --> 00:09:27,580
payload, your future self will thank you.
290
00:09:27,580 --> 00:09:30,420
Your reviewer will, too, memwise, heavy calls inside the block.
291
00:09:30,420 --> 00:09:32,220
Office 365 users, my profile V2,
292
00:09:32,220 --> 00:09:33,900
cache it once as CTX, user.
293
00:09:33,900 --> 00:09:35,140
Don't call it on every row.
294
00:09:35,140 --> 00:09:36,940
You eliminate jitter, you eliminate throttling,
295
00:09:36,940 --> 00:09:38,740
you eliminate lies, eliminate duplication
296
00:09:38,740 --> 00:09:40,540
with one local truth per screen.
297
00:09:40,540 --> 00:09:43,140
That gallery items formula copied across three controls,
298
00:09:43,140 --> 00:09:45,620
centralize it, with-by-stata, filter issues,
299
00:09:45,620 --> 00:09:48,260
starts with title, tick, search, text.
300
00:09:48,260 --> 00:09:51,460
Once if-count-ros data, data, table.
301
00:09:51,460 --> 00:09:53,460
Now, every downstream reference uses data.
302
00:09:53,460 --> 00:09:55,740
You change the filter once, everything follows,
303
00:09:55,740 --> 00:09:58,780
no hash drift, no ghosts, define shapes at the boundary.
304
00:09:58,780 --> 00:10:01,180
If a component expects a record with fields,
305
00:10:01,180 --> 00:10:04,980
A, B, C, enforce that inside with before you call it.
306
00:10:04,980 --> 00:10:07,060
With buffer, raw, look up issues,
307
00:10:07,060 --> 00:10:09,500
ID, a varselected id, model,
308
00:10:09,500 --> 00:10:13,820
al ID, raw, ID, title, coalesce, raw, title,
309
00:10:13,820 --> 00:10:18,780
Akin state, if-ice-blank-raw.state, open-raw-state,
310
00:10:18,780 --> 00:10:22,260
dot-by-comp-details-bond-input-eared-an-model.
311
00:10:22,260 --> 00:10:24,060
The model once, consume everywhere.
312
00:10:24,060 --> 00:10:26,100
That's a contract, that's control.
313
00:10:26,100 --> 00:10:27,780
Build a predictable patch payload,
314
00:10:27,780 --> 00:10:29,820
no loose records, no implicit coercion,
315
00:10:29,820 --> 00:10:31,060
with a form-edit-form issue,
316
00:10:31,060 --> 00:10:32,540
Rekkaus defaults-issues, model,
317
00:10:32,540 --> 00:10:34,780
on title, trim-form, updates-title,
318
00:10:34,780 --> 00:10:36,860
state-switch-form-update-state.
319
00:10:36,860 --> 00:10:45,140
Value, open-open-in-progress-in-progress-enclosed-closed-open-priority-value-form-updates.priority.
320
00:10:45,140 --> 00:10:49,300
Owner, if-ice-blankform.updates.owner,
321
00:10:49,300 --> 00:10:56,380
blank-or-lookup-users-email-equal-form-updates-bot-owner-email-mod-user,
322
00:10:56,380 --> 00:10:59,540
while payload-patch-rek-model.
323
00:10:59,540 --> 00:11:02,540
While patch-issues-rek-pay-load,
324
00:11:02,540 --> 00:11:05,300
notice the typeguards' option set labels normalized.
325
00:11:05,300 --> 00:11:07,740
Numbers-cost, lookups-resolved,
326
00:11:07,740 --> 00:11:10,180
you remove the power-effects, will figure it out-gamble.
327
00:11:10,180 --> 00:11:10,940
It won't.
328
00:11:10,940 --> 00:11:13,700
With removes the guesswork, root errors without side-effects,
329
00:11:13,700 --> 00:11:15,500
inside the with-catch tag return.
330
00:11:15,500 --> 00:11:18,260
With O-shankup, if error-patch-issues,
331
00:11:18,260 --> 00:11:21,980
lookup-issues-id, x, vass-elected-it, payload,
332
00:11:21,980 --> 00:11:26,860
OK, false, air, code, error-kind-message, error-message-den.
333
00:11:26,860 --> 00:11:30,740
If op, OK, notify-saved-notification-type.success,
334
00:11:30,740 --> 00:11:35,100
notify-failed-in-and-up-earth-message-notification-type-error.
335
00:11:35,100 --> 00:11:37,780
Better, never call-notify-directly from everywhere.
336
00:11:37,780 --> 00:11:40,060
Create an error channel with the attempt,
337
00:11:40,060 --> 00:11:43,060
if error-patch-issues, lookup-issues-id,
338
00:11:43,060 --> 00:11:49,540
eels-vass-elected-it, payload, OK, false, code, error-kind-message-error-message.
339
00:11:49,540 --> 00:11:55,220
Result, if-ice-blank-attempt, OK, true, code, blank-msg-al-attempt-event,
340
00:11:55,220 --> 00:12:00,180
by-kind, if-result, OK, success-and-failure, path-submit-issue, code-result,
341
00:12:00,180 --> 00:12:04,940
code-msg-result-msg-pil-tal-telemetry-event, if-result.
342
00:12:04,940 --> 00:12:08,820
OK, set-val-ass-saved-now-result, OK, inside-effects become explicit.
343
00:12:08,820 --> 00:12:12,500
One place, one exit, your UI checks a boolean, your logs capture the truth,
344
00:12:12,500 --> 00:12:15,460
no hidden branches, no psychic debugging.
345
00:12:15,460 --> 00:12:20,940
Memoirs-expensive transforms, with-push-base-filter-items-status-equal-active,
346
00:12:20,940 --> 00:12:26,220
enriched-add-columns-base-owner-name-lookup-user-id-l-owner-edophol-name,
347
00:12:26,220 --> 00:12:29,580
sort-by-columns-enriched-owner-name-you-comput-once,
348
00:12:29,580 --> 00:12:31,380
you sort-once-you-render-once,
349
00:12:31,380 --> 00:12:34,380
and your gallery doesn't recalc-owner-name-on-every-hover-performance
350
00:12:34,380 --> 00:12:36,900
is a symptom of structure, with-gives-you-structure.
351
00:12:36,900 --> 00:12:38,020
Guard input at the door.
352
00:12:38,020 --> 00:12:43,260
With K-E-Q, trim-tec search, text, normalized, lower-Q, safe, if-lan-normalized,
353
00:12:43,260 --> 00:12:47,580
two-blankers-normalized, world-if-eyes-blank-save-table, filter issues,
354
00:12:47,580 --> 00:12:49,980
starts with lower-title-save.
355
00:12:49,980 --> 00:12:54,060
No accidental full scans, no delegation-relate, a clear threshold you can test,
356
00:12:54,060 --> 00:12:57,700
two characters minimum, or whatever your SLO allows, one more truth.
357
00:12:57,700 --> 00:12:59,060
Don't nest with for-spot.
358
00:12:59,060 --> 00:13:03,420
Two levels, maybe three, beyond that extract to a user-defined function or a component,
359
00:13:03,420 --> 00:13:06,340
keep the local guardrail simple, readable, composable.
360
00:13:06,340 --> 00:13:10,180
Now the micro-story, a maker sent me a gallery that froze on scroll.
361
00:13:10,180 --> 00:13:13,100
They blamed dativerse, it was their formula, five separate ad-columns,
362
00:13:13,100 --> 00:13:17,020
each calling Office 365 users, I wrapped it in one with, cash the profile ones,
363
00:13:17,020 --> 00:13:19,900
moved all transforms into a single-enriched variable,
364
00:13:19,900 --> 00:13:23,380
freeze-gone, throttling-gone, ghost-gone, that's not magic, that's scope,
365
00:13:23,380 --> 00:13:25,420
everything changes when the screen stabilizes,
366
00:13:25,420 --> 00:13:27,820
because once a screen is predictable, you can extract it,
367
00:13:27,820 --> 00:13:32,060
componentize the header, the list, the editor, pass models, not globals,
368
00:13:32,060 --> 00:13:34,860
then the same guardrail protects every app that consumes them.
369
00:13:34,860 --> 00:13:38,380
Local discipline first, then boundaries, then environments where close,
370
00:13:38,380 --> 00:13:42,780
beyond the screen, components, UDFs and enhanced component properties.
371
00:13:42,780 --> 00:13:46,820
Local truth stabilizes a screen, but you don't scale by copying screens,
372
00:13:46,820 --> 00:13:47,860
you scale by contracts.
373
00:13:47,860 --> 00:13:51,220
Components are contracts, inputs, outputs, no hidden state,
374
00:13:51,220 --> 00:13:55,700
if you need state, you pass it in, you receive it out, you never smuggle it through, set.
375
00:13:55,700 --> 00:13:59,700
Here's the rule, a component is a black box with a spec, inputs declare shape,
376
00:13:59,700 --> 00:14:01,620
outputs declare events or models.
377
00:14:01,620 --> 00:14:06,420
No globals, no connector calls inside unless they're part of the components declared surface.
378
00:14:06,420 --> 00:14:11,180
If the component needs data, you give it data, if it needs to fetch, you give it a provider.
379
00:14:11,180 --> 00:14:14,420
Now enhanced component properties, this is where the contract grows teeth.
380
00:14:14,420 --> 00:14:19,180
You don't just pass primitive props, you pass logic, you expose formulas as configurable behavior,
381
00:14:19,180 --> 00:14:21,340
think slots, think policies.
382
00:14:21,340 --> 00:14:23,540
Example, a list header component.
383
00:14:23,540 --> 00:14:27,580
It renders a title, account and a search box, inputs, model,
384
00:14:27,580 --> 00:14:29,780
a title text, count number.
385
00:14:29,780 --> 00:14:33,580
On search, a formula that accepts text and returns a table theme.
386
00:14:33,580 --> 00:14:39,140
A record of tokens, not hard coded colors, outputs, search results, table events,
387
00:14:39,140 --> 00:14:42,220
unsubmitted, unclear inside, it holds no secrets.
388
00:14:42,220 --> 00:14:44,460
The search box calls the on search prop.
389
00:14:44,460 --> 00:14:46,900
The result flows back out through search results.
390
00:14:46,900 --> 00:14:50,940
The component never touches globals, it never reads tx search from the host screen.
391
00:14:50,940 --> 00:14:53,260
It speaks only through its properties, that's a contract.
392
00:14:53,260 --> 00:14:56,620
Enhanced component properties let you define on search as a formula prop,
393
00:14:56,620 --> 00:15:00,380
which means the host can inject a with patent search, normalized text, guard length,
394
00:15:00,380 --> 00:15:01,580
return a delegated query.
395
00:15:01,580 --> 00:15:05,460
The component just renders and relays, no drift, no blue dot lies.
396
00:15:05,460 --> 00:15:08,740
User defined functions fill the gap between repetition and reuse.
397
00:15:08,740 --> 00:15:13,220
When you catch yourself writing the same transform across three screens, extract a UDF,
398
00:15:13,220 --> 00:15:15,580
local to the app, pure no side effects.
399
00:15:15,580 --> 00:15:19,340
F and build issue model, record returns a normalized shape, always.
400
00:15:19,340 --> 00:15:21,660
F and patch issue, target, model.
401
00:15:21,660 --> 00:15:25,700
Builds the exact payload, coercive types, returns result with OK code MSG.
402
00:15:25,700 --> 00:15:27,820
These functions are testable, replaceable.
403
00:15:27,820 --> 00:15:30,060
You can switch their internals without touching callers.
404
00:15:30,060 --> 00:15:31,060
That's how you cut drift.
405
00:15:31,060 --> 00:15:35,780
Use UDFs for a model normalization type coercion and option set mapping, payload assembly,
406
00:15:35,780 --> 00:15:39,980
telemetry event creation, guard checks, image, F and I strong query query.
407
00:15:39,980 --> 00:15:44,660
Do not use UDFs for hidden global mutation ad hoc network calls buried inside helpers.
408
00:15:44,660 --> 00:15:45,500
Keep them pure.
409
00:15:45,500 --> 00:15:46,660
Keep them boring.
410
00:15:46,660 --> 00:15:47,940
Boring survives production.
411
00:15:47,940 --> 00:15:54,620
Now the bridge, components plus UDFs, the host screen uses width to prepare models.
412
00:15:54,620 --> 00:15:56,460
Calls UDFs to shape and validate.
413
00:15:56,460 --> 00:16:00,740
Feeds components through ECP formulas for behavior, the component raises events, the host
414
00:16:00,740 --> 00:16:06,340
logs through a telemetry UDF, one path in, one path out, scope, contract, boundary, enhanced
415
00:16:06,340 --> 00:16:08,380
component properties also unlock governance.
416
00:16:08,380 --> 00:16:12,260
You can ship a library component with required inputs typed by schema optional behavior
417
00:16:12,260 --> 00:16:16,940
slots with defaults feature flags enforced as booleans, not strings, theming via tokens,
418
00:16:16,940 --> 00:16:19,540
not hex values and you can version it.
419
00:16:19,540 --> 00:16:21,660
Library V.2 apps adopt when ready.
420
00:16:21,660 --> 00:16:27,580
Change log states added on validate behavior slot, deprecated on save raw, breaking changes
421
00:16:27,580 --> 00:16:32,740
documented, roll out staged, one fix, many apps, you kill the copy paste tree, themable design
422
00:16:32,740 --> 00:16:34,620
is not aesthetics, it's control.
423
00:16:34,620 --> 00:16:40,860
A theme prop is a record of tokens, surface text primary, accent, danger, spacing, radius,
424
00:16:40,860 --> 00:16:43,300
no hard coded styles, no strings buried in fill.
425
00:16:43,300 --> 00:16:47,100
When brand changes you swap theme once, every component respects it, consistency becomes
426
00:16:47,100 --> 00:16:48,100
automatic.
427
00:16:48,100 --> 00:16:50,100
Accessibility isn't an afterthought.
428
00:16:50,100 --> 00:16:54,460
High contrast maps to tokens instead of hand editing colors in 47 places.
429
00:16:54,460 --> 00:16:58,820
Crossup reuse demands discipline, no hidden connector calls in components that you can't
430
00:16:58,820 --> 00:17:03,580
mock no owner bound permissions inside a reusable part, no magic variable names you expect
431
00:17:03,580 --> 00:17:07,300
the host to provide, everything required must be a prop.
432
00:17:07,300 --> 00:17:11,340
Everything emitted must be an output or event, if a component needs a user it should take
433
00:17:11,340 --> 00:17:16,060
a user model prop, not call office 365 users, not once.
434
00:17:16,060 --> 00:17:17,660
Governance lives in the library.
435
00:17:17,660 --> 00:17:22,180
Incubating versioning enforced PR checks for component diffs and ECP signatures solution packaging
436
00:17:22,180 --> 00:17:27,620
with managed components, release notes embedded in the libraries about property, telemetry
437
00:17:27,620 --> 00:17:32,980
opt in via a behavior prop so hosts can inject their logging UDF, this is how you move fast
438
00:17:32,980 --> 00:17:35,620
without breaking the same things twice.
439
00:17:35,620 --> 00:17:39,900
A micro story, a team had five apps each with its own editor screen, same fields, different
440
00:17:39,900 --> 00:17:45,500
bugs, we extracted an issue editor component, inputs, issue model, on save, formula returning
441
00:17:45,500 --> 00:17:48,900
result, theme, outputs, on saved result, on canceled.
442
00:17:48,900 --> 00:17:52,700
We moved all field mapping into FN build issue model and FN patch issue.
443
00:17:52,700 --> 00:17:55,300
We exposed on validators and ECP behavior.
444
00:17:55,300 --> 00:17:58,180
One week later a schema change renamed priority to urgency.
445
00:17:58,180 --> 00:18:02,820
We updated the UDF mapping once, bumped the component to V1.1, pushed a managed solution,
446
00:18:02,820 --> 00:18:06,980
five apps fixed by adoption, no late night triage, no silent breakage in app 3 because
447
00:18:06,980 --> 00:18:11,940
someone missed a formula, contract hope, you want speed, you get it by removing choices,
448
00:18:11,940 --> 00:18:16,260
maintenance define form and flow, ECP define extension points UDF's defined truth, then
449
00:18:16,260 --> 00:18:17,820
ALM carries it safely.
450
00:18:17,820 --> 00:18:21,580
But that's next structure holds, therefore you can move to real environments.
451
00:18:21,580 --> 00:18:27,100
A real ALM solutions branches and safe releases, local discipline stabilizes a screen, contracts
452
00:18:27,100 --> 00:18:31,500
stabilize an app, but you still deploy like it's a file share, that's how you lose, solution
453
00:18:31,500 --> 00:18:35,540
first, not optional mandatory, a solution is the boundary, the unit of promotion, the
454
00:18:35,540 --> 00:18:40,780
audit trail, tables, apps, flows, component libraries, connection references, environment variables,
455
00:18:40,780 --> 00:18:45,660
unbundle, one identity, unmanaged in dev, managed everywhere else, because change without a
456
00:18:45,660 --> 00:18:48,340
boundary is just drift with a smile.
457
00:18:48,340 --> 00:18:52,300
Environments matter, dev test, prod, three names, three different privileges, dev, makers
458
00:18:52,300 --> 00:18:57,300
build, break, iterate, wild but contained, test limited makers, test data, service principles,
459
00:18:57,300 --> 00:19:01,740
no personal connections where you prove reality, prod, no making, only promoting.
460
00:19:01,740 --> 00:19:05,540
Minimal rights, if you edit in prod, you break the contract, whisper it, branches aren't
461
00:19:05,540 --> 00:19:09,860
ceremony, they're containment, keep main locked protected, feature branches per change,
462
00:19:09,860 --> 00:19:15,340
and by intent not by whim, feet, issue editor, ECP, fixed delegation query, chore, telemetry,
463
00:19:15,340 --> 00:19:19,940
UDF, open a PR, always you don't merge alone, you don't ship alone, because the second
464
00:19:19,940 --> 00:19:22,340
set of eyes catches the fracture you normalized.
465
00:19:22,340 --> 00:19:23,540
Code reviews for PowerFX?
466
00:19:23,540 --> 00:19:28,500
Yes, export the app, diff the MSAP text, or use source aligned tooling, you review.component
467
00:19:28,500 --> 00:19:29,980
signatures, props added or removed.
468
00:19:29,980 --> 00:19:34,820
UDF contracts, parameters, return shapes, purity maintained, formula drift, same intent,
469
00:19:34,820 --> 00:19:38,980
different implementation, explain it or kill it, delegation flags, blue dots are lies,
470
00:19:38,980 --> 00:19:40,860
prove delegation or gate the query.
471
00:19:40,860 --> 00:19:45,220
Connection references, stop binding flows and connectors to your identity, create references
472
00:19:45,220 --> 00:19:49,700
in the solution, bind them per environment, service principles for dataverse, sharepoint,
473
00:19:49,700 --> 00:19:54,100
outlook, least privilege, rotated secrets, documented owners, if a reviewer sees a personal
474
00:19:54,100 --> 00:20:01,020
connection in a PR reject, no exceptions, environment variables, no hard coded URLs, no table names,
475
00:20:01,020 --> 00:20:06,300
stitched into formulas, store base endpoints, tenant specific IDs, feature flags and reporting
476
00:20:06,300 --> 00:20:11,100
sync identifiers in ENV Vars, in dev point at mox, in test point at test services, in prod
477
00:20:11,100 --> 00:20:16,140
point at prod, without code change, feature flags let you ship dark, turn on paths gradually,
478
00:20:16,140 --> 00:20:21,460
kill switches ready, automated checks aren't optional, solution checker, fail the PR on critical
479
00:20:21,460 --> 00:20:22,940
issues.
480
00:20:22,940 --> 00:20:27,700
Performance Lint scan for non-delegible patterns in items of galleries and data calls, flag
481
00:20:27,700 --> 00:20:32,020
starts with over large sets without index, flag add columns in loops, accessibility Lint,
482
00:20:32,020 --> 00:20:37,020
trust against theme tokens, focus visuals present, tab order, same security lint, personal connections
483
00:20:37,020 --> 00:20:42,460
banned, set usage in components banned, globals in udf's banned, if it fails it doesn't merge,
484
00:20:42,460 --> 00:20:46,380
you don't argue with the gate, you fix it, pipelines carry trust, dev to test to prod with
485
00:20:46,380 --> 00:20:47,460
approvals.
486
00:20:47,460 --> 00:20:52,820
On import to test, apply environment variables, bind connection references, run post import
487
00:20:52,820 --> 00:20:59,580
smoke tests, open app, run synthetic, submit, approve report, publish telemetry check, do events
488
00:20:59,580 --> 00:21:03,460
land, are correlationites present, if any step fails, stop.
489
00:21:03,460 --> 00:21:09,220
Rollback automatically, no hero x version, everything, semantic 1.3 adds a feature, 1.3.1 fixes
490
00:21:09,220 --> 00:21:14,860
a bug, 2 breaks a contract, managed solutions in test and prod, always, hot fix channel, branch
491
00:21:14,860 --> 00:21:19,100
from the tag release, fix scoped, bump patch version, promote through the same gates, no quick
492
00:21:19,100 --> 00:21:23,500
fix in prod, that's how ghosts come back, rollback isn't a prayer, it's a plan, you keep the
493
00:21:23,500 --> 00:21:28,180
previous managed solution, you can uninstall the bad one and reapply the last good, or layer
494
00:21:28,180 --> 00:21:32,900
a hot fix solution to revert a component or udf quickly, data migrations version idemputent
495
00:21:32,900 --> 00:21:36,780
reversible where possible, and if you can't reverse you stop calling it a migration, you
496
00:21:36,780 --> 00:21:41,140
call it risk, approvals with context, sign offs mean something when you attach proof,
497
00:21:41,140 --> 00:21:46,700
include test evidence, green, yellow, red against SLOs for submit, approve report, delegation
498
00:21:46,700 --> 00:21:52,500
audit, queries and expected row counts, security diff, permission changes between environments,
499
00:21:52,500 --> 00:21:56,700
telemetry, snapshot, baseline performance versus current.
500
00:21:56,700 --> 00:22:01,660
Without this an approval is theater, you want safe releases, you get them by refusing ambiguity,
501
00:22:01,660 --> 00:22:08,820
solutions, environments, branches, PRs, references variables, checks, pipelines versions, rollback,
502
00:22:08,820 --> 00:22:14,540
not exciting, effective, now prove it under stress, proving resilience, tests, monitoring
503
00:22:14,540 --> 00:22:19,900
and controlled chaos, tests first, unit like udf assertions, component harness screens,
504
00:22:19,900 --> 00:22:24,780
synthetic end to end runs, telemetry everywhere, correlation id, duration outcome, define SLOs,
505
00:22:24,780 --> 00:22:29,340
state releases, drill chaos, throttle, expire tokens, rename fields, rotate certs, alert
506
00:22:29,340 --> 00:22:33,780
on failure, not feelings, green parts, stay green under stress, or you halt, the refactor
507
00:22:33,780 --> 00:22:39,300
plan, step by step, to neutralize chaos, inventory apps, screens variables, connectors, prioritized
508
00:22:39,300 --> 00:22:43,740
by impact and delegation risk, refactor screen by screen with width, extract components,
509
00:22:43,740 --> 00:22:49,380
udf, adopt theme tokens, standardize libraries, move into solutions, bind connection references,
510
00:22:49,380 --> 00:22:55,340
nvvas, add checks, tests, pipelines, rollback, lock governance, naming, reviews, telemetry,
511
00:22:55,340 --> 00:22:59,940
dashboards, repeat, expand, enforce, governance template, rules that make failure rare, you
512
00:22:59,940 --> 00:23:04,460
want prevention, not heroics, so we write the rules, we make failure rare by making ambiguity
513
00:23:04,460 --> 00:23:12,020
illegal, naming and contracts first, controls screen, issue list, dot gallery, main, not gallery
514
00:23:12,020 --> 00:23:19,520
one, variables, scn dot issueless dot dot selection, app theme, cmp dot editor dot model, prefix
515
00:23:19,520 --> 00:23:28,300
by scope, app scn cmp, fn, components, cmp dot issue editor v1.2, inputs and outputs typed
516
00:23:28,300 --> 00:23:34,340
in the about, no hidden props, no magic set, functions, fn build issue model, rack, fn patch
517
00:23:34,340 --> 00:23:39,460
issue target model, pure, always return a record with ok code msg allowed patterns with
518
00:23:39,460 --> 00:23:44,080
for local scope, mandatory on any formula longer than two lines, udfs for repeated transforms
519
00:23:44,080 --> 00:23:49,500
and payloads, pure, no connectors, enhanced component properties for behavior slots, on
520
00:23:49,500 --> 00:23:54,780
validate, on search, unsaved, typed, documented, theming via tokens, theme past as a record, no
521
00:23:54,780 --> 00:23:58,780
hex and fill, no strings in color, delegation aware queries only in gallery items and data
522
00:23:58,780 --> 00:24:03,740
calls, starts with on indexed columns, filter with equality, search only on bounded sets,
523
00:24:03,740 --> 00:24:08,900
prohibited patterns, global side effects in components, set inside a component is a defect,
524
00:24:08,900 --> 00:24:13,100
busy paste formulas across screens, one source of truth or you delete it, often collections,
525
00:24:13,100 --> 00:24:19,020
no collect on app, on start without refreshing owner, cash through explicit loaders with expiry,
526
00:24:19,020 --> 00:24:22,260
personal connections, any reference to your identity blocks the PR.
527
00:24:22,260 --> 00:24:26,620
Hidden state update context that toggles both UI and permission logic, split concerns
528
00:24:26,620 --> 00:24:30,780
or reject, review workflow every change goes through a PR, no emergency mergers, checklist
529
00:24:30,780 --> 00:24:35,100
in the PR description, component signature, diff reviewed udf purity verified delegation
530
00:24:35,100 --> 00:24:40,420
flags checked, row count expectations noted accessibility checked against tokens, security,
531
00:24:40,420 --> 00:24:44,380
connection references only, least privilege roles, telemetry calls present on submit approve
532
00:24:44,380 --> 00:24:48,900
report with correlation, it attached screenshots of solution checker paths, attached test evidence
533
00:24:48,900 --> 00:24:53,000
for green paths, if anything's yellow, justify or block, environment policy, who builds
534
00:24:53,000 --> 00:24:58,260
where is explicit, dev, make us free to experiment, unmanaged solutions only, test promotion
535
00:24:58,260 --> 00:25:03,260
by pipeline, managed only, service principles bound, test data ceded by script, no personal
536
00:25:03,260 --> 00:25:07,940
connectors, prod, promote only, no edits, audit trail required, if you must hot fix, it's
537
00:25:07,940 --> 00:25:13,140
a managed patch via pipeline with rollback ready, owners of environments listed, rotation scheduled,
538
00:25:13,140 --> 00:25:17,900
access reviewed monthly, monitoring policy, dashboards are required, not optional metrics,
539
00:25:17,900 --> 00:25:23,660
path duration, p95 for submit approve report, error rate by path and code delegation incidents
540
00:25:23,660 --> 00:25:28,820
detected versus resolved synthetic checks, success failure trend alerts, red path
541
00:25:28,820 --> 00:25:34,700
fires page, yellow logs ticket, green stays silent, connector 429 spikes trigger investigation,
542
00:25:34,700 --> 00:25:39,300
duplicate submission detector flags potential double rights, incident response steps correlation,
543
00:25:39,300 --> 00:25:44,020
it retrieved, blast radius assessed via dependency graph, rollback path validated or executed
544
00:25:44,020 --> 00:25:48,500
post incident report includes root cause, rule violated, rule updated, this is the template,
545
00:25:48,500 --> 00:25:52,340
short sharp you don't memorize it, you enforce it because structure without governance decays,
546
00:25:52,340 --> 00:25:57,780
so you lock it in the single takeaway and the CTA, our app fails, where you allow ambiguity,
547
00:25:57,780 --> 00:26:02,060
scope it with width, encapsulated in components bind it with solutions and prove it under
548
00:26:02,060 --> 00:26:06,540
stress, if this helped subscribe and grab the refactor plan and governance template in
549
00:26:06,540 --> 00:26:10,660
the next episode, audit one app today, kill one hidden dependency then tell me what broke
550
00:26:10,660 --> 00:26:11,500
and what you fixed.