Skip to content

Commit acb34ef

Browse files
committed
docs: general improvements
1 parent 4f5dbf7 commit acb34ef

File tree

11 files changed

+123
-139
lines changed

11 files changed

+123
-139
lines changed

docs/audit-stores/introduction.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public class App {
4848
var auditStore = new MongoDBSyncAuditStore(mongoClient, mongoDatabase);
4949

5050
// Register with Flamingock
51-
FlamingockStandalone
51+
Flamingock.builder()
5252
.setAuditStore(auditStore) // Set the audit store
5353
.addTargetSystems(myTargetSystem)
5454
.build()

docs/changes/best-practices.md

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,29 @@ public class _0002_FixUserFieldValues {
4646
}
4747
}
4848
```
49+
---
50+
51+
### Avoid domain object coupling
52+
53+
Building on the idea of immutability, another common pitfall is coupling Changes too tightly to domain objects. Changes are historical records that must remain stable over time, even as your application evolves. When Changes depend on domain classes that later change (fields removed, renamed, or restructured), your previously successful Changes can break compilation or execution.
54+
55+
**The issue:** If a Change uses a `Customer` domain class and you later remove the `middleName` field from that class, the Change will no longer compile - breaking Flamingock's ability to verify or re-execute historical changes.
56+
57+
**✅ Use generic structures instead:**
58+
```java
59+
// Instead of domain objects, use framework-native structures
60+
@Apply
61+
public void apply(JdbcTemplate jdbc) {
62+
Map<String, Object> customer = jdbc.queryForMap(
63+
"SELECT * FROM customers WHERE id = ?", customerId
64+
);
65+
// Work with the Map directly, not a Customer object
66+
}
67+
```
68+
69+
**Learn more:** [Domain Coupling and Historical Immutability](domain-coupling.md) - Understand why this happens and explore different approaches to keep your Changes stable.
70+
71+
---
4972

5073
### Always provide rollback logic
5174

@@ -82,23 +105,21 @@ public class _0001_SetupUserIndexes {
82105
@Rollback
83106
public void rollback(MongoDatabase database) {
84107
MongoCollection<Document> users = database.getCollection("users");
85-
86-
// Drop indexes in reverse order
87-
try {
108+
109+
// Drop only if the index exists
110+
if (isIndexCreated(users, "idx_user_search")) {
88111
users.dropIndex("idx_user_search");
89-
} catch (Exception e) {
90-
// Index might not exist - log but continue
91112
}
92-
93-
try {
94-
users.dropIndex("idx_user_email_status");
95-
} catch (Exception e) {
96-
// Index might not exist - log but continue
113+
114+
if (isIndexCreated(users, "idx_user_email_status")) {
115+
users.dropIndex("idx_user_email_status");
97116
}
98117
}
99118
}
100119
```
101120

121+
---
122+
102123
### Keep scope focused
103124

104125
Each Change should address one logical change. Avoid combining unrelated operations.
@@ -164,6 +185,9 @@ public class _0001_AddUserPreferences {
164185
}
165186
```
166187

188+
189+
---
190+
167191
### Handle errors gracefully
168192

169193
Don't catch exceptions unless you have specific recovery logic. Let Flamingock handle error management.
@@ -191,6 +215,9 @@ public void apply(MongoDatabase database) {
191215
}
192216
```
193217

218+
219+
---
220+
194221
### Use meaningful method names
195222

196223
Method names should clearly indicate their purpose.
@@ -207,27 +234,6 @@ public void addEmailIndexForFasterLookups(MongoDatabase db) { }
207234
public void removeEmailIndexAndRevertSchema(MongoDatabase db) { }
208235
```
209236

210-
### Avoid domain object coupling
211-
212-
Changes are historical records that must remain stable over time, even as your application evolves. When Changes depend on domain classes that later change (fields removed, renamed, or restructured), your previously successful Changes can break compilation or execution.
213-
214-
**The issue:** If a Change uses a `Customer` domain class and you later remove the `middleName` field from that class, the Change will no longer compile - breaking Flamingock's ability to verify or re-execute historical changes.
215-
216-
**✅ Use generic structures instead:**
217-
```java
218-
// Instead of domain objects, use framework-native structures
219-
@Apply
220-
public void apply(JdbcTemplate jdbc) {
221-
Map<String, Object> customer = jdbc.queryForMap(
222-
"SELECT * FROM customers WHERE id = ?", customerId
223-
);
224-
// Work with the Map directly, not a Customer object
225-
}
226-
```
227-
228-
**Learn more:** [Domain Coupling and Historical Immutability](domain-coupling.md) - Understand why this happens and explore different approaches to keep your Changes stable.
229-
230-
231237
## Naming and organization
232238

233239
### Follow consistent naming patterns
@@ -245,6 +251,9 @@ _0003_AddUserPreferences.java
245251
_0100_OptimizeUserQueries.java
246252
```
247253

254+
255+
---
256+
248257
### Use descriptive IDs and descriptions
249258

250259
Make your Changes self-documenting:
@@ -258,6 +267,9 @@ Make your Changes self-documenting:
258267
)
259268
```
260269

270+
271+
---
272+
261273
### Organize by chronological order
262274

263275
Changes should be organized chronologically by their order within stages. If you need logical grouping, use stages - but remember that execution order is only guaranteed within a stage, not between stages.
@@ -301,6 +313,9 @@ public void testUserMigrationChange() {
301313
}
302314
```
303315

316+
317+
---
318+
304319
### Validate with real-like data
305320

306321
Test with data that resembles production:

docs/changes/introduction.md

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ title: Introduction
33
sidebar_position: 1
44
---
55

6+
import Tabs from '@theme/Tabs';
7+
import TabItem from '@theme/TabItem';
8+
9+
610
# Changes
711

812
A **Change** is the atomic, versioned, self-contained unit of change in Flamingock. It encapsulates logic to evolve [**target systems**](../overview/audit-store-vs-target-system.md) safely, deterministically, and with complete auditability.
@@ -27,7 +31,9 @@ Changes enable you to version and track changes across your entire technology st
2731

2832
## Types of Changes
2933

30-
### Code-based Changes
34+
35+
<Tabs groupId="edition">
36+
<TabItem value="template" label="Template based" default>
3137
Written in Java, Kotlin, or Groovy with annotations. Best for complex logic or when you need full programmatic control.
3238

3339
```java
@@ -47,7 +53,8 @@ public class _0001_AddUserStatus {
4753
}
4854
```
4955

50-
### Template-based Changes
56+
</TabItem>
57+
<TabItem value="code" label="Code based">
5158
Use YAML or JSON definitions with reusable templates. Perfect for repetitive operations and standardized patterns.
5259

5360
```yaml
@@ -60,6 +67,11 @@ apply: "ALTER TABLE orders ADD COLUMN status VARCHAR(20);"
6067
rollback: "ALTER TABLE orders DROP COLUMN status;"
6168
```
6269
70+
</TabItem>
71+
</Tabs>
72+
73+
74+
6375
## Safety and recovery
6476
6577
While Change executions typically complete successfully, Flamingock provides configurable recovery strategies to handle any exceptional circumstances that may arise. If results are uncertain, Flamingock stops and requires manual intervention rather than risking data corruption, ensuring you always know the exact state of your systems.

docs/changes/types-and-implementation.md

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,53 @@ title: Types & Implementation
33
sidebar_position: 3
44
---
55

6+
7+
8+
import Tabs from '@theme/Tabs';
9+
import TabItem from '@theme/TabItem';
10+
611
# Change Types & Implementation
712

8-
Flamingock supports two approaches for implementing Changes: code-based and template-based. Each serves different use cases and provides the same safety guarantees.
13+
Flamingock supports two approaches for implementing Changes: **code-based** and **template-based**. Each serves different use cases and provides the same safety guarantees.
14+
15+
16+
17+
18+
19+
20+
21+
<Tabs groupId="edition">
22+
<TabItem value="template" label="Template based" default>
23+
Template-based Changes use YAML or JSON files with reusable templates. Templates provide a low-code, declarative approach for common patterns and repetitive operations. Templates can be as powerful and complex as code-based Changes - the difference is that templates are developed for reusable patterns and integrations.
24+
25+
### Basic YAML structure
26+
27+
```yaml
28+
# File: _0001_add_user_index.yml
29+
id: add_user_index
30+
order: "0001"
31+
author: "database-team"
32+
description: "Add index on user email field for faster lookups"
33+
targetSystem: "user-database"
34+
templateName: mongodb-index
35+
apply:
36+
type: createIndex
37+
collection: users
38+
indexSpec:
39+
email: 1
40+
options:
41+
unique: true
42+
name: "idx_user_email"
43+
rollback:
44+
type: removeIndex
45+
collection: users
46+
indexName: "idx_user_email"
47+
```
948
10-
## Code-based Changes
49+
For more details about available templates and creating custom templates, see [Templates](../templates/templates-introduction).
1150
51+
</TabItem>
52+
<TabItem value="code" label="Code based">
1253
Code-based Changes are written in Java, Kotlin, or Groovy with annotations. They provide full programmatic control for custom logic or specific operations that don't fit existing templates.
1354
1455
### Basic structure
@@ -37,35 +78,14 @@ public class _0001_MigrateUserEmails {
3778
}
3879
```
3980

40-
## Template-based Changes
81+
</TabItem>
82+
</Tabs>
83+
84+
4185

42-
Template-based Changes use YAML or JSON files with reusable templates. Templates provide a low-code, declarative approach for common patterns and repetitive operations. Templates can be as powerful and complex as code-based Changes - the difference is that templates are developed for reusable patterns and integrations.
4386

44-
### Basic YAML structure
4587

46-
```yaml
47-
# File: _0001_add_user_index.yml
48-
id: add_user_index
49-
order: "0001"
50-
author: "database-team"
51-
description: "Add index on user email field for faster lookups"
52-
targetSystem: "user-database"
53-
templateName: mongodb-index
54-
apply:
55-
type: createIndex
56-
collection: users
57-
indexSpec:
58-
email: 1
59-
options:
60-
unique: true
61-
name: "idx_user_email"
62-
rollback:
63-
type: removeIndex
64-
collection: users
65-
indexName: "idx_user_email"
66-
```
6788

68-
For more details about available templates and creating custom templates, see [Templates](../templates/templates-introduction).
6989

7090

7191
## File organization

docs/flamingock-library-config/additional-configuration.md

Lines changed: 2 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ This section includes additional settings for customizing defaults and adding co
1313
| Setting | Purpose | Default |
1414
|-----------------|-----------------------------------------------|--------------------|
1515
| `metadata` | Attach tags and labels for audit tracking | _empty map_ |
16-
| `defaultAuthor` | Used when no author is specified in a change | `"default_author"` |
1716
| `enabled` | Globally enable/disable Flamingock | `true` |
1817

1918
:::note
@@ -49,39 +48,14 @@ Map<String, Object> metadata = new HashMap<>();
4948
metadata.put("owner", "platform-team");
5049
metadata.put("triggeredBy", "ci-cd-pipeline");
5150

52-
FlamingockStandalone
51+
Flamingock.builder()
5352
.setMetadata(metadata)
5453
...
5554
```
5655
</TabItem>
5756
</Tabs>
5857

5958

60-
### Default Author
61-
62-
If a change unit does not specify an `author`, Flamingock will use this value as the fallback.
63-
64-
- Applies to both **code-based** and **template-based** changes
65-
- Default value: `"default_author"`
66-
- Ignored if the change itself defines an explicit author
67-
68-
### Example
69-
70-
<Tabs groupId="config">
71-
<TabItem value="file" label="YAML" default>
72-
```yaml
73-
defaultAuthor: antonio
74-
```
75-
</TabItem>
76-
<TabItem value="builder" label="Builder">
77-
```java
78-
FlamingockStandalone
79-
.setDefaultAuthor("antonio")
80-
```
81-
</TabItem>
82-
</Tabs>
83-
84-
8559
## Disable flamingock process
8660

8761
This global toggle allows you to enable or disable Flamingock.
@@ -104,7 +78,7 @@ enabled: false
10478
</TabItem>
10579
<TabItem value="builder" label="Builder">
10680
```java
107-
FlamingockStandalone
81+
Flamingock.builder()
10882
.setEnabled(false)
10983
```
11084
</TabItem>

docs/flamingock-library-config/context-and-dependencies.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Contexts can contain:
2222

2323
Flamingock uses a **hierarchical resolution strategy** that searches for dependencies in this order:
2424

25-
1. **Target system context** - Dependencies provided by the specific target system. For more information, see [Target systems](../target-systems/introduction.md).
25+
1. **Target system context** - Dependencies provided by the specific target system. For more information, see [Target systems](../target-systems/introduction.md#dependency-injection).
2626
2. **General application context** - Shared dependencies registered globally directly in the builder
2727
3. **Framework context** - When using Spring Boot, beans from the Spring container. For more information, see [Spring Boot integration](../frameworks/springboot-integration/introduction.md).
2828

docs/flamingock-library-config/events.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ In the Flamingock builder, you must configure the events you intend to use and i
4545
<Tabs groupId="languages">
4646
<TabItem value="java" label="Java" default>
4747
```java
48-
FlamingockStandalone.local()
48+
Flamingock.builder()
4949
.setPipelineStartedListener(new PipelineStartedListener())
5050
.setPipelineCompletedListener(new PipelineCompletedListener())
5151
.setPipelineFailedListener(new PipelineFailedListener())
@@ -58,7 +58,7 @@ In the Flamingock builder, you must configure the events you intend to use and i
5858
</TabItem>
5959
<TabItem value="kotlin" label="Kotlin">
6060
```kotlin
61-
FlamingockStandalone.local()
61+
Flamingock.builder()
6262
.setPipelineStartedListener(PipelineStartedListener())
6363
.setPipelineCompletedListener(PipelineCompletedListener())
6464
.setPipelineFailedListener(PipelineFailedListener())

docs/flamingock-library-config/lock.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ If you're injecting **non-critical components** (e.g., a local list or stateless
5454

5555
### Builder
5656
```java
57-
FlamingockStandalone
57+
Flamingock.builder()
5858
.setLockAcquiredForMillis(120000)
5959
.setLockQuitTryingAfterMillis(300000)
6060
.setLockTryFrequencyMillis(2000)

0 commit comments

Comments
 (0)