Skip to content

Commit cc01e2b

Browse files
committed
fix time dates and approvals
1 parent 4fd68e3 commit cc01e2b

39 files changed

+218
-202
lines changed

apps/workspace-engine/oapi/spec.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1002,6 +1002,7 @@ components:
10021002
type: string
10031003
createdAt:
10041004
type: string
1005+
format: date-time
10051006
workspaceId:
10061007
type: string
10071008
providerId:
@@ -1011,10 +1012,13 @@ components:
10111012
additionalProperties: true
10121013
lockedAt:
10131014
type: string
1015+
format: date-time
10141016
updatedAt:
10151017
type: string
1018+
format: date-time
10161019
deletedAt:
10171020
type: string
1021+
format: date-time
10181022
metadata:
10191023
type: object
10201024
additionalProperties:

apps/workspace-engine/pkg/changeset/changeset.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ const (
1515
)
1616

1717
type Change[T any] struct {
18-
Type ChangeType
19-
Entity T
20-
Timestamp time.Time
18+
Type ChangeType
19+
Entity T
20+
Timestamp time.Time
2121
}
2222

2323
type ChangeSet[T any] struct {

apps/workspace-engine/pkg/changeset/changeset_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ func TestChangeSetWithDedup_MixedEntities(t *testing.T) {
229229
cs.Record(ChangeTypeCreate, testEntity{ID: "resource-2", Name: "Resource 2"})
230230
cs.Record(ChangeTypeUpdate, testEntity{ID: "resource-1", Name: "Resource 1 Updated"}) // Duplicate
231231
cs.Record(ChangeTypeCreate, testEntity{ID: "resource-3", Name: "Resource 3"})
232-
cs.Record(ChangeTypeTaint, testEntity{ID: "resource-2", Name: "Resource 2"}) // Duplicate
232+
cs.Record(ChangeTypeTaint, testEntity{ID: "resource-2", Name: "Resource 2"}) // Duplicate
233233
cs.Record(ChangeTypeDelete, testEntity{ID: "resource-1", Name: "Resource 1"}) // Duplicate again
234234

235235
cs.Finalize()

apps/workspace-engine/pkg/changeset/processor.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -387,4 +387,3 @@ func (p *Processor[T]) Distinct(keyFunc func(Change[T]) string) *Processor[T] {
387387
errors: p.errors,
388388
}
389389
}
390-

apps/workspace-engine/pkg/changeset/processor_test.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ func TestProcessor_MapEntity(t *testing.T) {
9595
// Test sorting by timestamp
9696
func TestProcessor_SortByTimestamp(t *testing.T) {
9797
cs := NewChangeSet[TestEntity]()
98-
98+
9999
// Record with delays to ensure different timestamps
100100
cs.Record(ChangeTypeCreate, TestEntity{ID: "3", Name: "Third"})
101101
time.Sleep(2 * time.Millisecond)
@@ -119,7 +119,7 @@ func TestProcessor_SortByTimestamp(t *testing.T) {
119119
// Test sorting by timestamp descending
120120
func TestProcessor_SortByTimestampDesc(t *testing.T) {
121121
cs := NewChangeSet[TestEntity]()
122-
122+
123123
cs.Record(ChangeTypeCreate, TestEntity{ID: "1", Name: "First"})
124124
time.Sleep(2 * time.Millisecond)
125125
cs.Record(ChangeTypeUpdate, TestEntity{ID: "2", Name: "Second"})
@@ -654,7 +654,7 @@ func TestProcessor_TypeGuardWithValidation(t *testing.T) {
654654
guard := func(raw UnvalidatedConfig) (ValidatedConfig, bool) {
655655
host, hasHost := raw.Raw["host"]
656656
portStr, hasPort := raw.Raw["port"]
657-
657+
658658
if !hasHost || !hasPort {
659659
return ValidatedConfig{}, false
660660
}
@@ -749,4 +749,3 @@ func TestProcessor_ImmutableSource(t *testing.T) {
749749
t.Error("processor modified the original changeset")
750750
}
751751
}
752-

apps/workspace-engine/pkg/db/resources.go

Lines changed: 8 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -114,20 +114,10 @@ func scanResourceRow(row pgx.Row) (*oapi.Resource, error) {
114114
}
115115

116116
func setResourceTimestamps(resource *oapi.Resource, createdAt time.Time, lockedAt, updatedAt, deletedAt *time.Time) {
117-
resource.CreatedAt = createdAt.Format(time.RFC3339)
118-
119-
if lockedAt != nil {
120-
lockedAtStr := lockedAt.Format(time.RFC3339)
121-
resource.LockedAt = &lockedAtStr
122-
}
123-
if updatedAt != nil {
124-
updatedAtStr := updatedAt.Format(time.RFC3339)
125-
resource.UpdatedAt = &updatedAtStr
126-
}
127-
if deletedAt != nil {
128-
deletedAtStr := deletedAt.Format(time.RFC3339)
129-
resource.DeletedAt = &deletedAtStr
130-
}
117+
resource.CreatedAt = createdAt
118+
resource.LockedAt = lockedAt
119+
resource.UpdatedAt = updatedAt
120+
resource.DeletedAt = deletedAt
131121
}
132122

133123
func setResourceConfig(resource *oapi.Resource, configJSON []byte) error {
@@ -174,35 +164,6 @@ const RESOURCE_UPSERT_QUERY = `
174164
`
175165

176166
func writeResource(ctx context.Context, resource *oapi.Resource, tx pgx.Tx) error {
177-
// Parse timestamp strings to time.Time
178-
createdAt, err := time.Parse(time.RFC3339, resource.CreatedAt)
179-
if err != nil {
180-
return fmt.Errorf("failed to parse resource created_at: %w", err)
181-
}
182-
183-
var lockedAt, updatedAt, deletedAt *time.Time
184-
if resource.LockedAt != nil {
185-
t, err := time.Parse(time.RFC3339, *resource.LockedAt)
186-
if err != nil {
187-
return fmt.Errorf("failed to parse resource locked_at: %w", err)
188-
}
189-
lockedAt = &t
190-
}
191-
if resource.UpdatedAt != nil {
192-
t, err := time.Parse(time.RFC3339, *resource.UpdatedAt)
193-
if err != nil {
194-
return fmt.Errorf("failed to parse resource updated_at: %w", err)
195-
}
196-
updatedAt = &t
197-
}
198-
if resource.DeletedAt != nil {
199-
t, err := time.Parse(time.RFC3339, *resource.DeletedAt)
200-
if err != nil {
201-
return fmt.Errorf("failed to parse resource deleted_at: %w", err)
202-
}
203-
deletedAt = &t
204-
}
205-
206167
if _, err := tx.Exec(
207168
ctx,
208169
RESOURCE_UPSERT_QUERY,
@@ -214,10 +175,10 @@ func writeResource(ctx context.Context, resource *oapi.Resource, tx pgx.Tx) erro
214175
resource.ProviderId,
215176
resource.WorkspaceId,
216177
resource.Config,
217-
createdAt,
218-
lockedAt,
219-
updatedAt,
220-
deletedAt,
178+
resource.CreatedAt,
179+
resource.LockedAt,
180+
resource.UpdatedAt,
181+
resource.DeletedAt,
221182
); err != nil {
222183
return err
223184
}

apps/workspace-engine/pkg/db/resources_test.go

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@ import (
1010
"github.com/google/uuid"
1111
)
1212

13+
func compareTimePtr(t *testing.T, actual *time.Time, expected *time.Time) {
14+
t.Helper()
15+
if actual == nil && expected == nil {
16+
return
17+
}
18+
if actual == nil || expected == nil {
19+
t.Fatalf("expected %v, got %v", expected, actual)
20+
}
21+
// Compare with some tolerance for database timestamp precision
22+
if actual.Unix() != expected.Unix() {
23+
t.Fatalf("expected %v, got %v", expected, actual)
24+
}
25+
}
26+
1327
func validateRetrievedResources(t *testing.T, actualResources []*oapi.Resource, expectedResources []*oapi.Resource) {
1428
t.Helper()
1529
if len(actualResources) != len(expectedResources) {
@@ -76,15 +90,15 @@ func validateRetrievedResources(t *testing.T, actualResources []*oapi.Resource,
7690
}
7791

7892
// Validate timestamps (basic presence check)
79-
if actualResource.CreatedAt == "" {
93+
if actualResource.CreatedAt.IsZero() {
8094
t.Fatalf("expected resource created_at to be set")
8195
}
82-
compareStrPtr(t, actualResource.LockedAt, expectedResource.LockedAt)
96+
compareTimePtr(t, actualResource.LockedAt, expectedResource.LockedAt)
8397
// Note: updated_at can be set by DB on update, so we just check if expected is set
8498
if expectedResource.UpdatedAt != nil && actualResource.UpdatedAt == nil {
8599
t.Fatalf("expected resource updated_at to be set")
86100
}
87-
compareStrPtr(t, actualResource.DeletedAt, expectedResource.DeletedAt)
101+
compareTimePtr(t, actualResource.DeletedAt, expectedResource.DeletedAt)
88102
}
89103
}
90104

@@ -100,7 +114,7 @@ func TestDBResources_BasicWrite(t *testing.T) {
100114

101115
id := uuid.New().String()
102116
name := fmt.Sprintf("test-resource-%s", id[:8])
103-
createdAt := time.Now().Format(time.RFC3339)
117+
createdAt := time.Now()
104118
resource := &oapi.Resource{
105119
Id: id,
106120
Version: "v1",
@@ -150,7 +164,7 @@ func TestDBResources_BasicWriteAndDelete(t *testing.T) {
150164

151165
id := uuid.New().String()
152166
name := fmt.Sprintf("test-resource-%s", id[:8])
153-
createdAt := time.Now().Format(time.RFC3339)
167+
createdAt := time.Now()
154168
resource := &oapi.Resource{
155169
Id: id,
156170
Version: "v1",
@@ -221,7 +235,7 @@ func TestDBResources_BasicWriteAndUpdate(t *testing.T) {
221235

222236
id := uuid.New().String()
223237
name := fmt.Sprintf("test-resource-%s", id[:8])
224-
createdAt := time.Now().Format(time.RFC3339)
238+
createdAt := time.Now()
225239
resource := &oapi.Resource{
226240
Id: id,
227241
Version: "v1",
@@ -296,7 +310,7 @@ func TestDBResources_MetadataUpdate(t *testing.T) {
296310

297311
id := uuid.New().String()
298312
name := fmt.Sprintf("test-resource-%s", id[:8])
299-
createdAt := time.Now().Format(time.RFC3339)
313+
createdAt := time.Now()
300314
resource := &oapi.Resource{
301315
Id: id,
302316
Version: "v1",
@@ -366,7 +380,7 @@ func TestDBResources_EmptyMetadata(t *testing.T) {
366380

367381
id := uuid.New().String()
368382
name := fmt.Sprintf("test-resource-%s", id[:8])
369-
createdAt := time.Now().Format(time.RFC3339)
383+
createdAt := time.Now()
370384
resource := &oapi.Resource{
371385
Id: id,
372386
Version: "v1",
@@ -409,9 +423,9 @@ func TestDBResources_WithTimestamps(t *testing.T) {
409423

410424
id := uuid.New().String()
411425
name := fmt.Sprintf("test-resource-%s", id[:8])
412-
createdAt := time.Now().Add(-24 * time.Hour).Format(time.RFC3339)
413-
lockedAt := time.Now().Add(-1 * time.Hour).Format(time.RFC3339)
414-
updatedAt := time.Now().Format(time.RFC3339)
426+
createdAt := time.Now().Add(-24 * time.Hour)
427+
lockedAt := time.Now().Add(-1 * time.Hour)
428+
updatedAt := time.Now()
415429
resource := &oapi.Resource{
416430
Id: id,
417431
Version: "v1",
@@ -456,7 +470,7 @@ func TestDBResources_ComplexConfig(t *testing.T) {
456470

457471
id := uuid.New().String()
458472
name := fmt.Sprintf("test-resource-%s", id[:8])
459-
createdAt := time.Now().Format(time.RFC3339)
473+
createdAt := time.Now()
460474
resource := &oapi.Resource{
461475
Id: id,
462476
Version: "v1",
@@ -505,7 +519,7 @@ func TestDBResources_NonexistentWorkspaceThrowsError(t *testing.T) {
505519
}
506520
defer tx.Rollback(t.Context())
507521

508-
createdAt := time.Now().Format(time.RFC3339)
522+
createdAt := time.Now()
509523
resource := &oapi.Resource{
510524
Id: uuid.New().String(),
511525
Version: "v1",
@@ -540,7 +554,7 @@ func TestDBResources_MultipleResources(t *testing.T) {
540554
}
541555
defer tx.Rollback(t.Context())
542556

543-
createdAt := time.Now().Format(time.RFC3339)
557+
createdAt := time.Now()
544558
resources := []*oapi.Resource{
545559
{
546560
Id: uuid.New().String(),
@@ -610,7 +624,7 @@ func TestDBResources_WorkspaceIsolation(t *testing.T) {
610624
}
611625
defer tx1.Rollback(t.Context())
612626

613-
createdAt := time.Now().Format(time.RFC3339)
627+
createdAt := time.Now()
614628
resource1 := &oapi.Resource{
615629
Id: uuid.New().String(),
616630
Version: "v1",
@@ -697,8 +711,8 @@ func TestDBResources_SoftDeleteFiltering(t *testing.T) {
697711
}
698712
defer tx.Rollback(t.Context())
699713

700-
createdAt := time.Now().Format(time.RFC3339)
701-
deletedAt := time.Now().Format(time.RFC3339)
714+
createdAt := time.Now()
715+
deletedAt := time.Now()
702716

703717
// Create a resource with deleted_at set (soft deleted)
704718
softDeletedResource := &oapi.Resource{

apps/workspace-engine/pkg/kafka/kafka.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ func RunConsumer(ctx context.Context) error {
6161
}
6262

6363
msg, err := c.ReadMessage(time.Second)
64-
64+
6565
if err != nil {
6666
if err.(kafka.Error).IsTimeout() {
6767
log.Debug("Timeout, continuing")

apps/workspace-engine/pkg/oapi/oapi.gen.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

apps/workspace-engine/pkg/selector/langs/jsonselector/util/reflect.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,23 @@ func GetDateProperty(entity any, fieldName string) (time.Time, error) {
6161
return time.Time{}, err
6262
}
6363

64-
if field.Kind() != reflect.String {
65-
return time.Time{}, fmt.Errorf("field %s is not a string", fieldName)
64+
// Handle time.Time directly
65+
if field.Type() == reflect.TypeOf(time.Time{}) {
66+
return field.Interface().(time.Time), nil
67+
}
68+
69+
// Handle *time.Time
70+
if field.Type() == reflect.TypeOf((*time.Time)(nil)) {
71+
if field.IsNil() {
72+
return time.Time{}, fmt.Errorf("field %s is nil", fieldName)
73+
}
74+
return field.Elem().Interface().(time.Time), nil
75+
}
76+
77+
// Handle string (for backward compatibility)
78+
if field.Kind() == reflect.String {
79+
return time.Parse(time.RFC3339, field.String())
6680
}
6781

68-
return time.Parse(time.RFC3339, field.String())
82+
return time.Time{}, fmt.Errorf("field %s is not a time.Time or string", fieldName)
6983
}

0 commit comments

Comments
 (0)