-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathseeds.rb
More file actions
488 lines (454 loc) · 46.7 KB
/
seeds.rb
File metadata and controls
488 lines (454 loc) · 46.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
NODES = [
# --- Events ---
{ name: "wroclove.rb 2018", kind: "event", short_description: "Ruby conference in Wrocław, March 2018.", description: "Single-track, non-profit Ruby conference.", attrs: { "format" => "in-person", "date" => "2018-03-16", "location" => "Wrocław, Poland" } },
{ name: "wroclove.rb 2019", kind: "event", short_description: "Ruby conference in Wrocław, March 2019.", description: "Single-track, non-profit Ruby conference.", attrs: { "format" => "in-person", "date" => "2019-03-22", "location" => "Wrocław, Poland" } },
{ name: "wroclove.rb 2022", kind: "event", short_description: "Ruby conference in Wrocław, March 2022.", description: "Single-track, non-profit Ruby conference.", attrs: { "format" => "in-person", "date" => "2022-03-11", "location" => "Wrocław, Poland" } },
{ name: "wroclove.rb 2023", kind: "event", short_description: "Ruby conference in Wrocław, March 2023.", description: "Single-track, non-profit Ruby conference.", attrs: { "format" => "in-person", "date" => "2023-03-31", "location" => "Wrocław, Poland" } },
{ name: "wroclove.rb 2024", kind: "event", short_description: "Ruby conference in Wrocław, March 2024.", description: "Single-track, non-profit Ruby conference.", attrs: { "format" => "in-person", "date" => "2024-03-22", "location" => "Wrocław, Poland" } },
{ name: "wroclove.rb 2025", kind: "event", short_description: "Ruby conference in Wrocław, March 2025.", description: "Single-track, non-profit Ruby conference.", attrs: { "format" => "in-person", "date" => "2025-03-14", "location" => "Wrocław, Poland" } },
{ name: "wroclove.rb 2026", kind: "event", short_description: "Ruby conference in Wrocław, April 2026.", description: "3-day, single-track, non-profit Ruby conference. 12 talks + 4 workshops.", attrs: { "format" => "in-person", "date" => "2026-04-17", "location" => "Wrocław, Poland" } },
# --- Persons ---
{ name: "Adam Okoń", kind: "person", short_description: "Ruby developer, agentic workflows.", description: "Ruby developer building agentic AI workflows." },
{ name: "Adam Piotrowski", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Adrian Marin", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Agnieszka Małaszkiewicz", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Amelia Walter-Dzikowska", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Andrei Bondarev", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Andrei Kaleshka", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Andrzej Krzywda", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Andrzej Śliwa", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Andy Maleh", kind: "person", short_description: "Creator of Glimmer DSL.", description: "Creator of Glimmer DSL, building Rails SPAs with web components." },
{ name: "Anita Jaszewska", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Anton Davydov", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Armin Pašalić", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Ayush Newatia", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Bartosz Blimke", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Caio Almeida", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Charles Nutter", kind: "person", short_description: "JRuby co-creator.", description: "Co-creator of JRuby, long-time Ruby and JVM community member." },
{ name: "Chikahiro Tokoro", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Krzysztof Hasiński", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Damir Zekić", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "David Halasz", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Dimitry Salahutdinov", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Emiliano Della Casa", kind: "person", short_description: "Ruby developer, alternative protocols.", description: "Ruby developer working with alternative protocols beyond REST." },
{ name: "Erwin Kroon", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Ethan Garofolo", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Greg Molnar", kind: "person", short_description: "Rails security expert.", description: "Rails security consultant and workshop facilitator." },
{ name: "Ismael Celis", kind: "person", short_description: "Ruby developer, event sourcing practitioner.", description: "Ruby developer exploring event sourcing and actor model patterns." },
{ name: "Ivan Nemytchenko", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Jakub Rodzik", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Janko Marohnic", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Joel Drapper", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "John Gallagher", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Josef Strzibny", kind: "person", short_description: "Author of Deployment from Scratch.", description: "Developer and author focused on deployment and infrastructure." },
{ name: "Julik Tarkhanov", kind: "person", short_description: "Ruby developer, durable execution.", description: "Ruby developer exploring durable execution patterns." },
{ name: "Karol Szuster", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Krzysztof Hasiński", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Kuba Suder", kind: "person", short_description: "macOS/iOS and Ruby developer.", description: "Developer building on Bluesky's AT Protocol with Ruby." },
{ name: "Louis Antonopoulos", kind: "person", short_description: "Ruby developer.", description: "Ruby developer, speaker on Ractor and concurrency." },
{ name: "Maciej Rząsa", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Marco Heimeshoff", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Mariusz Gil", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Markus Schirp", kind: "person", short_description: "Creator of Mutant, mutation testing expert.", description: "Creator of Mutant — mutation testing tool for Ruby." },
{ name: "Martin Gamsjaeger", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Mateusz Nowak", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Michal Matyas", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Michał Młoźniak", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Michał Zajączkowski de Mezer", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Miron Marczuk", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Nathan Ladd", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Nick Sutterer", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Nicolò Rebughini", kind: "person", short_description: "Ruby developer, ML in Ruby.", description: "Ruby developer who accidentally built a neural network for product recommendations." },
{ name: "Norbert Wójtowicz", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Paweł Dąbrowski", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Paweł Pokrywka", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Paweł Strzałkowski", kind: "person", short_description: "Ruby developer, AI and MCP.", description: "Ruby developer building production AI apps with MCP and OAuth." },
{ name: "Radoslav Stankov", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Rafał Cymerys", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Rafał Rothenberger", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Ryan Townsend", kind: "person", short_description: "Ruby developer, no-build frontend.", description: "Ruby developer advocating modern UX with Rails and web standards." },
{ name: "Scott Bellware", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Sebastian Wilgosz", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Sergey Sergyenko", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Seth Horsley", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Sharon Rosner", kind: "person", short_description: "Creator of Polyphony and UringMachine.", description: "Ruby developer focused on high-performance concurrency with io_uring." },
{ name: "Stefan Wintermeyer", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Stephen Margheim", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Szymon Fiedler", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Tomasz Donarski", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Victor Shepelev", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Vladimir Dementyev", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Wojtek Wrona", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Yaroslav Shmarov", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Yatish Mehta", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Łukasz Reszke", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
{ name: "Łukasz Szydło", kind: "person", short_description: "Conference speaker.", description: "Conference speaker." },
# --- Talks: wroclove.rb 2018 ---
{ name: "Applying CQRS & Event Sourcing on Rails applications", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Better WebPerformance with Rails", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Beyond the current state Time travel to the rescue!", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Cables! Cables! Cables!", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Counterintuitive Rails pt. 1", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Counterintuitive Rails pt. 2", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Event Sourcing Anti Patterns and Failures", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "MVCC for Ruby developers", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "SUPER AIN'T SUPER From OOP To FP and Beyond!", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "The pillars of Domain Driven Design", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Toolbelt of a Seasoned Bug Hunter", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
{ name: "Understanding coupling", kind: "talk", short_description: "Talk at wroclove.rb 2018.", attrs: { "type" => "talk" } },
# --- Talks: wroclove.rb 2019 ---
{ name: "Building uls for microservices", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Business logic in Ruby", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Development with axioms", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Events events events", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Handling file uploads for modern developer", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "How to hijack", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Mutant on steroids", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Optimistic ul", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Orchestrating video transcoding in ruby", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Spice up your life with eql", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
{ name: "Towards the post framework future", kind: "talk", short_description: "Talk at wroclove.rb 2019.", attrs: { "type" => "talk" } },
# --- Talks: wroclove.rb 2022 ---
{ name: "How To Package A Rails Engine Generation To Automation", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Typical DDDomains In Rails Apps", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Dealing With A Project's Complexity In A Changing Environment", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Nightmare neighbours caveats of Rails based mutlitenancy", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Ever shorter feedback loop", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "The good, the bad and the remote — collaborative domain modeling with EventStorming", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "How To Ensure Systems Do What We Want And Take Care Of Themselves", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "10 Things You Never Wanted To Know About Reform 3", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Grokking FP For The Practicing Rubyist", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Under The Hood And On The Surface Of Sidekiq", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Introduction To Event Sourcing How To Use It With Ruby", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Devise pitfalls and way to tighten security", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "Data Management With Ruby", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
{ name: "18 months of using hotwire and viewcomponent in production", kind: "talk", short_description: "Talk at wroclove.rb 2022.", attrs: { "type" => "talk" } },
# --- Talks: wroclove.rb 2023 ---
{ name: "Ruby Rendezvous Method Call, Proc, and Beyond", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "International cooperation in IT teams", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "Native apps are dead, long live native apps", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "Fantastic Databases and Where to Find Them", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "Testing Randomness", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "Multi-region data governance in Rails application", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "An Introduction to Test Bench", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "From open source to IPO", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "Doctrine of Useful Objects Separate Fact from Fiction in OOD", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "Reforging (or rather rebrewing) the support for open-source", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
{ name: "Working with RailsEventStore in Cashflow Management System", kind: "talk", short_description: "Talk at wroclove.rb 2023.", attrs: { "type" => "talk" } },
# --- Talks: wroclove.rb 2024 ---
{ name: "Prevent account sharing", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "Building LLM powered applications in Ruby", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "How I brought LCP down to under 350 ms", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "The Curse of Service Object", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "Introducing Sorbet into your Ruby codebase", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "Extracting logic from templates with Hanami Views", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "One machine please, make it Turing", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "How (and why) to run SQLite in production", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "Optimizing performance in Rails apps with GraphQL layer", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "Debug like a scientist", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "Component Driven UI with ViewComponent", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
{ name: "Webmock unmocked", kind: "talk", short_description: "Talk at wroclove.rb 2024.", attrs: { "type" => "talk" } },
# --- Talks: wroclove.rb 2025 ---
{ name: "Ruby has literally always had types", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "Is the monolith a problem", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "Building Beautiful UIs with Ruby A Rails-Native Approach", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "From PostgreSQL to SQLite in Rails", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "It is not so bad, after all", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "Next Token!", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "Fix Production Bugs 20x Faster", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "On the tasteful journey to Yippee", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "No 'Pundit' Intended", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "Rewrite with confidence", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "Might & Magic of Domain-Driven Design", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
{ name: "Gregorian Calendar", kind: "talk", short_description: "Talk at wroclove.rb 2025.", attrs: { "type" => "talk" } },
# --- Talks: wroclove.rb 2026 ---
{ name: "JRuby: Professional-Grade Ruby", kind: "talk", short_description: "Talk on JRuby's capabilities.", attrs: { "type" => "talk" } },
{ name: "Kamal is not harder than your PaaS", kind: "talk", short_description: "Talk on Kamal deployment.", attrs: { "type" => "talk" } },
{ name: "My core skill never was the typing", kind: "talk", short_description: "Talk on mutation testing philosophy.", attrs: { "type" => "talk" } },
{ name: "Event Sourcing and Actor model in Ruby", kind: "talk", short_description: "Talk on event sourcing and actors.", attrs: { "type" => "talk" } },
{ name: "Rubyana Gems and the Ractorous Rubetta Stones!", kind: "talk", short_description: "Talk on Ractor and concurrency.", attrs: { "type" => "talk" } },
{ name: "Accidentally building a neural network — A Ruby product recommendation journey", kind: "talk", short_description: "Talk on ML product recommendations in Ruby.", attrs: { "type" => "talk" } },
{ name: "UringMachine — High Performance Concurrency for Ruby Using io_uring", kind: "talk", short_description: "Talk on io_uring concurrency in Ruby.", attrs: { "type" => "talk" } },
{ name: "Forms Are Dead: Building Agentic Workflows in Ruby", kind: "talk", short_description: "Talk on agentic AI workflows.", attrs: { "type" => "talk" } },
{ name: "Adventures in durable execution", kind: "talk", short_description: "Talk on durable execution patterns.", attrs: { "type" => "talk" } },
{ name: "Building on Bluesky's AT Protocol with Ruby", kind: "talk", short_description: "Talk on AT Protocol and Ruby.", attrs: { "type" => "talk" } },
{ name: "When REST is Not Enough: Implementing Alternative Protocols in Ruby on Rails", kind: "talk", short_description: "Talk on alternative protocols in Ruby on Rails.", attrs: { "type" => "talk" } },
{ name: "No-build Utopia: Modern User Experiences with Rails & Web Standards", kind: "talk", short_description: "Talk on no-build frontend with Rails.", attrs: { "type" => "talk" } },
# --- Workshops: wroclove.rb 2026 ---
{ name: "Setup and operation of mutation testing in agentic world", kind: "talk", short_description: "Workshop on mutation testing.", attrs: { "type" => "workshop" } },
{ name: "Securing Rails applications", kind: "talk", short_description: "Workshop on Rails security.", attrs: { "type" => "workshop" } },
{ name: "Building a Production-Ready AI App: MCP & OAuth on Rails", kind: "talk", short_description: "Workshop on AI apps with MCP and OAuth.", attrs: { "type" => "workshop" } },
{ name: "Building Rails SPAs in Frontend Ruby with Glimmer DSL for Web", kind: "talk", short_description: "Workshop on Glimmer DSL for Web.", attrs: { "type" => "workshop" } }
]
EDGES = [
# --- authored (2018) ---
{ source: "Andrzej Śliwa", target: "Applying CQRS & Event Sourcing on Rails applications", relation: "authored" },
{ source: "Stefan Wintermeyer", target: "Better WebPerformance with Rails", relation: "authored" },
{ source: "Armin Pašalić", target: "Beyond the current state Time travel to the rescue!", relation: "authored" },
{ source: "Vladimir Dementyev", target: "Cables! Cables! Cables!", relation: "authored" },
{ source: "Ivan Nemytchenko", target: "Counterintuitive Rails pt. 1", relation: "authored" },
{ source: "Ivan Nemytchenko", target: "Counterintuitive Rails pt. 2", relation: "authored" },
{ source: "Nathan Ladd", target: "Event Sourcing Anti Patterns and Failures", relation: "authored" },
{ source: "Michał Młoźniak", target: "MVCC for Ruby developers", relation: "authored" },
{ source: "Nick Sutterer", target: "SUPER AIN'T SUPER From OOP To FP and Beyond!", relation: "authored" },
{ source: "Marco Heimeshoff", target: "The pillars of Domain Driven Design", relation: "authored" },
{ source: "Damir Zekić", target: "Toolbelt of a Seasoned Bug Hunter", relation: "authored" },
{ source: "Łukasz Szydło", target: "Understanding coupling", relation: "authored" },
# --- authored (2019) ---
{ source: "Ethan Garofolo", target: "Building uls for microservices", relation: "authored" },
{ source: "Andrzej Krzywda", target: "Business logic in Ruby", relation: "authored" },
{ source: "Martin Gamsjaeger", target: "Development with axioms", relation: "authored" },
{ source: "Anton Davydov", target: "Events events events", relation: "authored" },
{ source: "Janko Marohnic", target: "Handling file uploads for modern developer", relation: "authored" },
{ source: "David Halasz", target: "How to hijack", relation: "authored" },
{ source: "Markus Schirp", target: "Mutant on steroids", relation: "authored" },
{ source: "Dimitry Salahutdinov", target: "Optimistic ul", relation: "authored" },
{ source: "Michal Matyas", target: "Orchestrating video transcoding in ruby", relation: "authored" },
{ source: "Norbert Wójtowicz", target: "Spice up your life with eql", relation: "authored" },
{ source: "Victor Shepelev", target: "Towards the post framework future", relation: "authored" },
# --- authored (2022) ---
{ source: "Adrian Marin", target: "How To Package A Rails Engine Generation To Automation", relation: "authored" },
{ source: "Andrzej Krzywda", target: "Typical DDDomains In Rails Apps", relation: "authored" },
{ source: "Anita Jaszewska", target: "Dealing With A Project's Complexity In A Changing Environment", relation: "authored" },
{ source: "Karol Szuster", target: "Nightmare neighbours caveats of Rails based mutlitenancy", relation: "authored" },
{ source: "Krzysztof Hasiński", target: "Ever shorter feedback loop", relation: "authored" },
{ source: "Mariusz Gil", target: "The good, the bad and the remote — collaborative domain modeling with EventStorming", relation: "authored" },
{ source: "Michał Zajączkowski de Mezer", target: "How To Ensure Systems Do What We Want And Take Care Of Themselves", relation: "authored" },
{ source: "Nick Sutterer", target: "10 Things You Never Wanted To Know About Reform 3", relation: "authored" },
{ source: "Norbert Wójtowicz", target: "Grokking FP For The Practicing Rubyist", relation: "authored" },
{ source: "Paweł Dąbrowski", target: "Under The Hood And On The Surface Of Sidekiq", relation: "authored" },
{ source: "Paweł Strzałkowski", target: "Introduction To Event Sourcing How To Use It With Ruby", relation: "authored" },
{ source: "Rafał Rothenberger", target: "Devise pitfalls and way to tighten security", relation: "authored" },
{ source: "Sergey Sergyenko", target: "Data Management With Ruby", relation: "authored" },
{ source: "Yaroslav Shmarov", target: "18 months of using hotwire and viewcomponent in production", relation: "authored" },
# --- authored (2023) ---
{ source: "Agnieszka Małaszkiewicz", target: "Ruby Rendezvous Method Call, Proc, and Beyond", relation: "authored" },
{ source: "Amelia Walter-Dzikowska", target: "International cooperation in IT teams", relation: "authored" },
{ source: "Ayush Newatia", target: "Native apps are dead, long live native apps", relation: "authored" },
{ source: "Krzysztof Hasiński", target: "Fantastic Databases and Where to Find Them", relation: "authored" },
{ source: "Jakub Rodzik", target: "Testing Randomness", relation: "authored" },
{ source: "Miron Marczuk", target: "Multi-region data governance in Rails application", relation: "authored" },
{ source: "Nathan Ladd", target: "An Introduction to Test Bench", relation: "authored" },
{ source: "Rafał Cymerys", target: "From open source to IPO", relation: "authored" },
{ source: "Scott Bellware", target: "Doctrine of Useful Objects Separate Fact from Fiction in OOD", relation: "authored" },
{ source: "Tomasz Donarski", target: "Reforging (or rather rebrewing) the support for open-source", relation: "authored" },
{ source: "Łukasz Reszke", target: "Working with RailsEventStore in Cashflow Management System", relation: "authored" },
# --- authored (2024) ---
{ source: "Andrei Kaleshka", target: "Prevent account sharing", relation: "authored" },
{ source: "Andrei Bondarev", target: "Building LLM powered applications in Ruby", relation: "authored" },
{ source: "Paweł Pokrywka", target: "How I brought LCP down to under 350 ms", relation: "authored" },
{ source: "Ivan Nemytchenko", target: "The Curse of Service Object", relation: "authored" },
{ source: "Erwin Kroon", target: "Introducing Sorbet into your Ruby codebase", relation: "authored" },
{ source: "Sebastian Wilgosz", target: "Extracting logic from templates with Hanami Views", relation: "authored" },
{ source: "David Halasz", target: "One machine please, make it Turing", relation: "authored" },
{ source: "Stephen Margheim", target: "How (and why) to run SQLite in production", relation: "authored" },
{ source: "Caio Almeida", target: "Optimizing performance in Rails apps with GraphQL layer", relation: "authored" },
{ source: "Maciej Rząsa", target: "Debug like a scientist", relation: "authored" },
{ source: "Radoslav Stankov", target: "Component Driven UI with ViewComponent", relation: "authored" },
{ source: "Bartosz Blimke", target: "Webmock unmocked", relation: "authored" },
# --- authored (2025) ---
{ source: "Joel Drapper", target: "Ruby has literally always had types", relation: "authored" },
{ source: "Chikahiro Tokoro", target: "Is the monolith a problem", relation: "authored" },
{ source: "Seth Horsley", target: "Building Beautiful UIs with Ruby A Rails-Native Approach", relation: "authored" },
{ source: "Wojtek Wrona", target: "From PostgreSQL to SQLite in Rails", relation: "authored" },
{ source: "Adam Piotrowski", target: "It is not so bad, after all", relation: "authored" },
{ source: "Krzysztof Hasiński", target: "Next Token!", relation: "authored" },
{ source: "John Gallagher", target: "Fix Production Bugs 20x Faster", relation: "authored" },
{ source: "Stephen Margheim", target: "On the tasteful journey to Yippee", relation: "authored" },
{ source: "Yatish Mehta", target: "No 'Pundit' Intended", relation: "authored" },
{ source: "Szymon Fiedler", target: "Rewrite with confidence", relation: "authored" },
{ source: "Mateusz Nowak", target: "Might & Magic of Domain-Driven Design", relation: "authored" },
{ source: "Norbert Wójtowicz", target: "Gregorian Calendar", relation: "authored" },
# --- authored (2026) ---
{ source: "Charles Nutter", target: "JRuby: Professional-Grade Ruby", relation: "authored" },
{ source: "Josef Strzibny", target: "Kamal is not harder than your PaaS", relation: "authored" },
{ source: "Markus Schirp", target: "My core skill never was the typing", relation: "authored" },
{ source: "Ismael Celis", target: "Event Sourcing and Actor model in Ruby", relation: "authored" },
{ source: "Louis Antonopoulos", target: "Rubyana Gems and the Ractorous Rubetta Stones!", relation: "authored" },
{ source: "Nicolò Rebughini", target: "Accidentally building a neural network — A Ruby product recommendation journey", relation: "authored" },
{ source: "Sharon Rosner", target: "UringMachine — High Performance Concurrency for Ruby Using io_uring", relation: "authored" },
{ source: "Adam Okoń", target: "Forms Are Dead: Building Agentic Workflows in Ruby", relation: "authored" },
{ source: "Julik Tarkhanov", target: "Adventures in durable execution", relation: "authored" },
{ source: "Kuba Suder", target: "Building on Bluesky's AT Protocol with Ruby", relation: "authored" },
{ source: "Emiliano Della Casa", target: "When REST is Not Enough: Implementing Alternative Protocols in Ruby on Rails", relation: "authored" },
{ source: "Ryan Townsend", target: "No-build Utopia: Modern User Experiences with Rails & Web Standards", relation: "authored" },
{ source: "Markus Schirp", target: "Setup and operation of mutation testing in agentic world", relation: "authored" },
{ source: "Greg Molnar", target: "Securing Rails applications", relation: "authored" },
{ source: "Paweł Strzałkowski", target: "Building a Production-Ready AI App: MCP & OAuth on Rails", relation: "authored" },
{ source: "Andy Maleh", target: "Building Rails SPAs in Frontend Ruby with Glimmer DSL for Web", relation: "authored" },
# --- presented_at (2018) ---
{ source: "Applying CQRS & Event Sourcing on Rails applications", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Better WebPerformance with Rails", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Beyond the current state Time travel to the rescue!", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Cables! Cables! Cables!", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Counterintuitive Rails pt. 1", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Counterintuitive Rails pt. 2", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Event Sourcing Anti Patterns and Failures", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "MVCC for Ruby developers", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "SUPER AIN'T SUPER From OOP To FP and Beyond!", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "The pillars of Domain Driven Design", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Toolbelt of a Seasoned Bug Hunter", target: "wroclove.rb 2018", relation: "presented_at" },
{ source: "Understanding coupling", target: "wroclove.rb 2018", relation: "presented_at" },
# --- presented_at (2019) ---
{ source: "Building uls for microservices", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Business logic in Ruby", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Development with axioms", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Events events events", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Handling file uploads for modern developer", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "How to hijack", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Mutant on steroids", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Optimistic ul", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Orchestrating video transcoding in ruby", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Spice up your life with eql", target: "wroclove.rb 2019", relation: "presented_at" },
{ source: "Towards the post framework future", target: "wroclove.rb 2019", relation: "presented_at" },
# --- presented_at (2022) ---
{ source: "How To Package A Rails Engine Generation To Automation", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Typical DDDomains In Rails Apps", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Dealing With A Project's Complexity In A Changing Environment", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Nightmare neighbours caveats of Rails based mutlitenancy", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Ever shorter feedback loop", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "The good, the bad and the remote — collaborative domain modeling with EventStorming", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "How To Ensure Systems Do What We Want And Take Care Of Themselves", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "10 Things You Never Wanted To Know About Reform 3", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Grokking FP For The Practicing Rubyist", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Under The Hood And On The Surface Of Sidekiq", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Introduction To Event Sourcing How To Use It With Ruby", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Devise pitfalls and way to tighten security", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "Data Management With Ruby", target: "wroclove.rb 2022", relation: "presented_at" },
{ source: "18 months of using hotwire and viewcomponent in production", target: "wroclove.rb 2022", relation: "presented_at" },
# --- presented_at (2023) ---
{ source: "Ruby Rendezvous Method Call, Proc, and Beyond", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "International cooperation in IT teams", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "Native apps are dead, long live native apps", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "Fantastic Databases and Where to Find Them", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "Testing Randomness", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "Multi-region data governance in Rails application", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "An Introduction to Test Bench", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "From open source to IPO", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "Doctrine of Useful Objects Separate Fact from Fiction in OOD", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "Reforging (or rather rebrewing) the support for open-source", target: "wroclove.rb 2023", relation: "presented_at" },
{ source: "Working with RailsEventStore in Cashflow Management System", target: "wroclove.rb 2023", relation: "presented_at" },
# --- presented_at (2024) ---
{ source: "Prevent account sharing", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "Building LLM powered applications in Ruby", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "How I brought LCP down to under 350 ms", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "The Curse of Service Object", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "Introducing Sorbet into your Ruby codebase", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "Extracting logic from templates with Hanami Views", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "One machine please, make it Turing", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "How (and why) to run SQLite in production", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "Optimizing performance in Rails apps with GraphQL layer", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "Debug like a scientist", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "Component Driven UI with ViewComponent", target: "wroclove.rb 2024", relation: "presented_at" },
{ source: "Webmock unmocked", target: "wroclove.rb 2024", relation: "presented_at" },
# --- presented_at (2025) ---
{ source: "Ruby has literally always had types", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "Is the monolith a problem", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "Building Beautiful UIs with Ruby A Rails-Native Approach", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "From PostgreSQL to SQLite in Rails", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "It is not so bad, after all", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "Next Token!", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "Fix Production Bugs 20x Faster", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "On the tasteful journey to Yippee", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "No 'Pundit' Intended", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "Rewrite with confidence", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "Might & Magic of Domain-Driven Design", target: "wroclove.rb 2025", relation: "presented_at" },
{ source: "Gregorian Calendar", target: "wroclove.rb 2025", relation: "presented_at" },
# --- presented_at (2026) ---
{ source: "JRuby: Professional-Grade Ruby", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Kamal is not harder than your PaaS", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "My core skill never was the typing", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Event Sourcing and Actor model in Ruby", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Rubyana Gems and the Ractorous Rubetta Stones!", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Accidentally building a neural network — A Ruby product recommendation journey", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "UringMachine — High Performance Concurrency for Ruby Using io_uring", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Forms Are Dead: Building Agentic Workflows in Ruby", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Adventures in durable execution", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Building on Bluesky's AT Protocol with Ruby", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "When REST is Not Enough: Implementing Alternative Protocols in Ruby on Rails", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "No-build Utopia: Modern User Experiences with Rails & Web Standards", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Setup and operation of mutation testing in agentic world", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Securing Rails applications", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Building a Production-Ready AI App: MCP & OAuth on Rails", target: "wroclove.rb 2026", relation: "presented_at" },
{ source: "Building Rails SPAs in Frontend Ruby with Glimmer DSL for Web", target: "wroclove.rb 2026", relation: "presented_at" }
]
# --- Seed nodes ---
nodes_by_name = {}
NODES.each do |data|
slug = data[:name].parameterize
node = Node.find_or_initialize_by(slug: slug)
node.assign_attributes(name: data[:name], kind: data[:kind], short_description: data[:short_description], description: data[:description] || data[:short_description], attrs: (node.attrs || {}).merge(data[:attrs] || {}))
node.save!
nodes_by_name[data[:name]] = node
begin
text = node.short_description.present? ? "#{node.name} — #{node.short_description}" : "#{node.name} (#{node.kind})"
response = RubyLLM.embed(text, model: "qwen3-embedding:4b", provider: :ollama, assume_model_exists: true)
node.update_columns(embedding: "[#{response.vectors.join(",")}]")
print "\rEmbedded #{nodes_by_name.size} nodes..."
rescue => e
puts "\nFailed to embed #{data[:name]}: #{e.message}"
end
end
puts "\nNodes seeded: #{Node.count}"
# --- Seed edges ---
EDGES.each do |data|
source = nodes_by_name[data[:source]]
target = nodes_by_name[data[:target]]
next unless source && target
edge = Edge.find_or_initialize_by(source_node: source, target_node: target, relation: data[:relation])
edge.context = data[:context] if data[:context]
edge.attrs = (edge.attrs || {}).merge(data[:attrs] || {}) if data[:attrs]
edge.save!
end
puts "Edges seeded: #{Edge.count}"
# --- Ingest transcripts ---
transcripts_dir = Rails.root.join("transcripts")
event_store = Rails.configuration.event_store
event_dates = NODES
.select { |n| n[:kind] == "event" }
.each_with_object({}) do |n, h|
date = n.dig(:attrs, "date") or next
h[n[:name]] = Time.utc(*date.split("-").map(&:to_i), 9, 0, 0)
end
event_dates.each do |event_name, event_time|
event_dir = transcripts_dir.join(event_name)
next unless event_dir.exist?
puts "\n=== Ingesting #{event_name} ==="
files = Dir.glob(event_dir.join("*.{txt,vtt}")).sort_by { |path| File.basename(path) }
files.each do |path|
filename = File.basename(path)
kind =
case filename
when /\.panel\.txt$/ then "panel"
when /\.lightning\.txt$/ then "lightning-talks"
else "talk"
end
content = File.read(path)
content_hash = Digest::SHA256.hexdigest(content)
ingestion_id = SecureRandom.uuid
event = TranscriptIngested.new(
data: {
ingestion_id: ingestion_id,
format: "transcript",
kind: kind,
content_hash: content_hash,
content: content,
external_id: filename,
metadata: { filename: filename, event: event_name }
},
metadata: {
valid_at: event_time
}
)
begin
event_store.publish(
event,
stream_name: "Ingestion$#{content_hash}",
expected_version: :none
)
puts " OK #{filename} → #{kind}"
rescue RubyEventStore::WrongExpectedEventVersion
puts " DUP #{filename} — already ingested"
end
end
end