feat(config): unified [auto] section with preview config and backward compat
Add preview fields to Config struct and load them from viper under the new [auto.preview] TOML section. Backward compatibility maintained: auto_route.enabled and auto_route_allowed_domains old keys are still read as fallback. Add GetPreviewConfig, IsPreviewEnabled, IsAutoEnabled, GetPreviewTagPatterns, and GetAllowedDomains methods to ConfigService interface with implementations and updated mockery mock.
- commit
- 3daa0361db832af5deb35347f3b75aefbed37f53
- author
- brice · · 2026-03-19 04:53 UTC
- committer
- brice · · 2026-03-19 05:13 UTC
- parent
- 07aac7d
- signature
- unsigned
3 files · +314 -4
M internal/boundaries/in/config.go +7 -0
| @@ -84,4 +84,11 @@ type ConfigService interface { | |||
| 84 | 84 | GetAutoRouteAllowedDomains(ctx context.Context) ([]string, error) | |
| 85 | 85 | AddAutoRouteAllowedDomain(ctx context.Context, pattern string) error | |
| 86 | 86 | RemoveAutoRouteAllowedDomain(ctx context.Context, pattern string) error | |
| 87 | + | ||
| 88 | + | // Preview and auto config | |
| 89 | + | GetPreviewConfig() domain.PreviewConfig | |
| 90 | + | IsPreviewEnabled() bool | |
| 91 | + | IsAutoEnabled() bool | |
| 92 | + | GetPreviewTagPatterns() []string | |
| 93 | + | GetAllowedDomains() []string | |
| 87 | 94 | } | |
| @@ -84,4 +84,11 @@ type ConfigService interface { | |||||
| 84 | GetAutoRouteAllowedDomains(ctx context.Context) ([]string, error) | 84 | GetAutoRouteAllowedDomains(ctx context.Context) ([]string, error) | ||
| 85 | AddAutoRouteAllowedDomain(ctx context.Context, pattern string) error | 85 | AddAutoRouteAllowedDomain(ctx context.Context, pattern string) error | ||
| 86 | RemoveAutoRouteAllowedDomain(ctx context.Context, pattern string) error | 86 | RemoveAutoRouteAllowedDomain(ctx context.Context, pattern string) error | ||
| 87 | + | ||||
| 88 | + | // Preview and auto config | |||
| 89 | + | GetPreviewConfig() domain.PreviewConfig | |||
| 90 | + | IsPreviewEnabled() bool | |||
| 91 | + | IsAutoEnabled() bool | |||
| 92 | + | GetPreviewTagPatterns() []string | |||
| 93 | + | GetAllowedDomains() []string | |||
| 87 | } | 94 | } | ||
M internal/boundaries/in/mocks/mock_config_service.go +224 -0
| @@ -1378,6 +1378,230 @@ func (_c *MockConfigService_UpdateRoute_Call) RunAndReturn(run func(ctx context. | |||
| 1378 | 1378 | return _c | |
| 1379 | 1379 | } | |
| 1380 | 1380 | ||
| 1381 | + | // GetPreviewConfig provides a mock function for the type MockConfigService | |
| 1382 | + | func (_mock *MockConfigService) GetPreviewConfig() domain.PreviewConfig { | |
| 1383 | + | ret := _mock.Called() | |
| 1384 | + | ||
| 1385 | + | if len(ret) == 0 { | |
| 1386 | + | panic("no return value specified for GetPreviewConfig") | |
| 1387 | + | } | |
| 1388 | + | ||
| 1389 | + | var r0 domain.PreviewConfig | |
| 1390 | + | if returnFunc, ok := ret.Get(0).(func() domain.PreviewConfig); ok { | |
| 1391 | + | r0 = returnFunc() | |
| 1392 | + | } else { | |
| 1393 | + | r0 = ret.Get(0).(domain.PreviewConfig) | |
| 1394 | + | } | |
| 1395 | + | return r0 | |
| 1396 | + | } | |
| 1397 | + | ||
| 1398 | + | // MockConfigService_GetPreviewConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPreviewConfig' | |
| 1399 | + | type MockConfigService_GetPreviewConfig_Call struct { | |
| 1400 | + | *mock.Call | |
| 1401 | + | } | |
| 1402 | + | ||
| 1403 | + | // GetPreviewConfig is a helper method to define mock.On call | |
| 1404 | + | func (_e *MockConfigService_Expecter) GetPreviewConfig() *MockConfigService_GetPreviewConfig_Call { | |
| 1405 | + | return &MockConfigService_GetPreviewConfig_Call{Call: _e.mock.On("GetPreviewConfig")} | |
| 1406 | + | } | |
| 1407 | + | ||
| 1408 | + | func (_c *MockConfigService_GetPreviewConfig_Call) Run(run func()) *MockConfigService_GetPreviewConfig_Call { | |
| 1409 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1410 | + | run() | |
| 1411 | + | }) | |
| 1412 | + | return _c | |
| 1413 | + | } | |
| 1414 | + | ||
| 1415 | + | func (_c *MockConfigService_GetPreviewConfig_Call) Return(cfg domain.PreviewConfig) *MockConfigService_GetPreviewConfig_Call { | |
| 1416 | + | _c.Call.Return(cfg) | |
| 1417 | + | return _c | |
| 1418 | + | } | |
| 1419 | + | ||
| 1420 | + | func (_c *MockConfigService_GetPreviewConfig_Call) RunAndReturn(run func() domain.PreviewConfig) *MockConfigService_GetPreviewConfig_Call { | |
| 1421 | + | _c.Call.Return(run) | |
| 1422 | + | return _c | |
| 1423 | + | } | |
| 1424 | + | ||
| 1425 | + | // IsPreviewEnabled provides a mock function for the type MockConfigService | |
| 1426 | + | func (_mock *MockConfigService) IsPreviewEnabled() bool { | |
| 1427 | + | ret := _mock.Called() | |
| 1428 | + | ||
| 1429 | + | if len(ret) == 0 { | |
| 1430 | + | panic("no return value specified for IsPreviewEnabled") | |
| 1431 | + | } | |
| 1432 | + | ||
| 1433 | + | var r0 bool | |
| 1434 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |
| 1435 | + | r0 = returnFunc() | |
| 1436 | + | } else { | |
| 1437 | + | r0 = ret.Get(0).(bool) | |
| 1438 | + | } | |
| 1439 | + | return r0 | |
| 1440 | + | } | |
| 1441 | + | ||
| 1442 | + | // MockConfigService_IsPreviewEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsPreviewEnabled' | |
| 1443 | + | type MockConfigService_IsPreviewEnabled_Call struct { | |
| 1444 | + | *mock.Call | |
| 1445 | + | } | |
| 1446 | + | ||
| 1447 | + | // IsPreviewEnabled is a helper method to define mock.On call | |
| 1448 | + | func (_e *MockConfigService_Expecter) IsPreviewEnabled() *MockConfigService_IsPreviewEnabled_Call { | |
| 1449 | + | return &MockConfigService_IsPreviewEnabled_Call{Call: _e.mock.On("IsPreviewEnabled")} | |
| 1450 | + | } | |
| 1451 | + | ||
| 1452 | + | func (_c *MockConfigService_IsPreviewEnabled_Call) Run(run func()) *MockConfigService_IsPreviewEnabled_Call { | |
| 1453 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1454 | + | run() | |
| 1455 | + | }) | |
| 1456 | + | return _c | |
| 1457 | + | } | |
| 1458 | + | ||
| 1459 | + | func (_c *MockConfigService_IsPreviewEnabled_Call) Return(b bool) *MockConfigService_IsPreviewEnabled_Call { | |
| 1460 | + | _c.Call.Return(b) | |
| 1461 | + | return _c | |
| 1462 | + | } | |
| 1463 | + | ||
| 1464 | + | func (_c *MockConfigService_IsPreviewEnabled_Call) RunAndReturn(run func() bool) *MockConfigService_IsPreviewEnabled_Call { | |
| 1465 | + | _c.Call.Return(run) | |
| 1466 | + | return _c | |
| 1467 | + | } | |
| 1468 | + | ||
| 1469 | + | // IsAutoEnabled provides a mock function for the type MockConfigService | |
| 1470 | + | func (_mock *MockConfigService) IsAutoEnabled() bool { | |
| 1471 | + | ret := _mock.Called() | |
| 1472 | + | ||
| 1473 | + | if len(ret) == 0 { | |
| 1474 | + | panic("no return value specified for IsAutoEnabled") | |
| 1475 | + | } | |
| 1476 | + | ||
| 1477 | + | var r0 bool | |
| 1478 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |
| 1479 | + | r0 = returnFunc() | |
| 1480 | + | } else { | |
| 1481 | + | r0 = ret.Get(0).(bool) | |
| 1482 | + | } | |
| 1483 | + | return r0 | |
| 1484 | + | } | |
| 1485 | + | ||
| 1486 | + | // MockConfigService_IsAutoEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsAutoEnabled' | |
| 1487 | + | type MockConfigService_IsAutoEnabled_Call struct { | |
| 1488 | + | *mock.Call | |
| 1489 | + | } | |
| 1490 | + | ||
| 1491 | + | // IsAutoEnabled is a helper method to define mock.On call | |
| 1492 | + | func (_e *MockConfigService_Expecter) IsAutoEnabled() *MockConfigService_IsAutoEnabled_Call { | |
| 1493 | + | return &MockConfigService_IsAutoEnabled_Call{Call: _e.mock.On("IsAutoEnabled")} | |
| 1494 | + | } | |
| 1495 | + | ||
| 1496 | + | func (_c *MockConfigService_IsAutoEnabled_Call) Run(run func()) *MockConfigService_IsAutoEnabled_Call { | |
| 1497 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1498 | + | run() | |
| 1499 | + | }) | |
| 1500 | + | return _c | |
| 1501 | + | } | |
| 1502 | + | ||
| 1503 | + | func (_c *MockConfigService_IsAutoEnabled_Call) Return(b bool) *MockConfigService_IsAutoEnabled_Call { | |
| 1504 | + | _c.Call.Return(b) | |
| 1505 | + | return _c | |
| 1506 | + | } | |
| 1507 | + | ||
| 1508 | + | func (_c *MockConfigService_IsAutoEnabled_Call) RunAndReturn(run func() bool) *MockConfigService_IsAutoEnabled_Call { | |
| 1509 | + | _c.Call.Return(run) | |
| 1510 | + | return _c | |
| 1511 | + | } | |
| 1512 | + | ||
| 1513 | + | // GetPreviewTagPatterns provides a mock function for the type MockConfigService | |
| 1514 | + | func (_mock *MockConfigService) GetPreviewTagPatterns() []string { | |
| 1515 | + | ret := _mock.Called() | |
| 1516 | + | ||
| 1517 | + | if len(ret) == 0 { | |
| 1518 | + | panic("no return value specified for GetPreviewTagPatterns") | |
| 1519 | + | } | |
| 1520 | + | ||
| 1521 | + | var r0 []string | |
| 1522 | + | if returnFunc, ok := ret.Get(0).(func() []string); ok { | |
| 1523 | + | r0 = returnFunc() | |
| 1524 | + | } else { | |
| 1525 | + | if ret.Get(0) != nil { | |
| 1526 | + | r0 = ret.Get(0).([]string) | |
| 1527 | + | } | |
| 1528 | + | } | |
| 1529 | + | return r0 | |
| 1530 | + | } | |
| 1531 | + | ||
| 1532 | + | // MockConfigService_GetPreviewTagPatterns_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPreviewTagPatterns' | |
| 1533 | + | type MockConfigService_GetPreviewTagPatterns_Call struct { | |
| 1534 | + | *mock.Call | |
| 1535 | + | } | |
| 1536 | + | ||
| 1537 | + | // GetPreviewTagPatterns is a helper method to define mock.On call | |
| 1538 | + | func (_e *MockConfigService_Expecter) GetPreviewTagPatterns() *MockConfigService_GetPreviewTagPatterns_Call { | |
| 1539 | + | return &MockConfigService_GetPreviewTagPatterns_Call{Call: _e.mock.On("GetPreviewTagPatterns")} | |
| 1540 | + | } | |
| 1541 | + | ||
| 1542 | + | func (_c *MockConfigService_GetPreviewTagPatterns_Call) Run(run func()) *MockConfigService_GetPreviewTagPatterns_Call { | |
| 1543 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1544 | + | run() | |
| 1545 | + | }) | |
| 1546 | + | return _c | |
| 1547 | + | } | |
| 1548 | + | ||
| 1549 | + | func (_c *MockConfigService_GetPreviewTagPatterns_Call) Return(patterns []string) *MockConfigService_GetPreviewTagPatterns_Call { | |
| 1550 | + | _c.Call.Return(patterns) | |
| 1551 | + | return _c | |
| 1552 | + | } | |
| 1553 | + | ||
| 1554 | + | func (_c *MockConfigService_GetPreviewTagPatterns_Call) RunAndReturn(run func() []string) *MockConfigService_GetPreviewTagPatterns_Call { | |
| 1555 | + | _c.Call.Return(run) | |
| 1556 | + | return _c | |
| 1557 | + | } | |
| 1558 | + | ||
| 1559 | + | // GetAllowedDomains provides a mock function for the type MockConfigService | |
| 1560 | + | func (_mock *MockConfigService) GetAllowedDomains() []string { | |
| 1561 | + | ret := _mock.Called() | |
| 1562 | + | ||
| 1563 | + | if len(ret) == 0 { | |
| 1564 | + | panic("no return value specified for GetAllowedDomains") | |
| 1565 | + | } | |
| 1566 | + | ||
| 1567 | + | var r0 []string | |
| 1568 | + | if returnFunc, ok := ret.Get(0).(func() []string); ok { | |
| 1569 | + | r0 = returnFunc() | |
| 1570 | + | } else { | |
| 1571 | + | if ret.Get(0) != nil { | |
| 1572 | + | r0 = ret.Get(0).([]string) | |
| 1573 | + | } | |
| 1574 | + | } | |
| 1575 | + | return r0 | |
| 1576 | + | } | |
| 1577 | + | ||
| 1578 | + | // MockConfigService_GetAllowedDomains_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllowedDomains' | |
| 1579 | + | type MockConfigService_GetAllowedDomains_Call struct { | |
| 1580 | + | *mock.Call | |
| 1581 | + | } | |
| 1582 | + | ||
| 1583 | + | // GetAllowedDomains is a helper method to define mock.On call | |
| 1584 | + | func (_e *MockConfigService_Expecter) GetAllowedDomains() *MockConfigService_GetAllowedDomains_Call { | |
| 1585 | + | return &MockConfigService_GetAllowedDomains_Call{Call: _e.mock.On("GetAllowedDomains")} | |
| 1586 | + | } | |
| 1587 | + | ||
| 1588 | + | func (_c *MockConfigService_GetAllowedDomains_Call) Run(run func()) *MockConfigService_GetAllowedDomains_Call { | |
| 1589 | + | _c.Call.Run(func(args mock.Arguments) { | |
| 1590 | + | run() | |
| 1591 | + | }) | |
| 1592 | + | return _c | |
| 1593 | + | } | |
| 1594 | + | ||
| 1595 | + | func (_c *MockConfigService_GetAllowedDomains_Call) Return(domains []string) *MockConfigService_GetAllowedDomains_Call { | |
| 1596 | + | _c.Call.Return(domains) | |
| 1597 | + | return _c | |
| 1598 | + | } | |
| 1599 | + | ||
| 1600 | + | func (_c *MockConfigService_GetAllowedDomains_Call) RunAndReturn(run func() []string) *MockConfigService_GetAllowedDomains_Call { | |
| 1601 | + | _c.Call.Return(run) | |
| 1602 | + | return _c | |
| 1603 | + | } | |
| 1604 | + | ||
| 1381 | 1605 | // Watch provides a mock function for the type MockConfigService | |
| 1382 | 1606 | func (_mock *MockConfigService) Watch(ctx context.Context, onChange func()) error { | |
| 1383 | 1607 | ret := _mock.Called(ctx, onChange) | |
| @@ -1378,6 +1378,230 @@ func (_c *MockConfigService_UpdateRoute_Call) RunAndReturn(run func(ctx context. | |||||
| 1378 | return _c | 1378 | return _c | ||
| 1379 | } | 1379 | } | ||
| 1380 | 1380 | ||||
| 1381 | + | // GetPreviewConfig provides a mock function for the type MockConfigService | |||
| 1382 | + | func (_mock *MockConfigService) GetPreviewConfig() domain.PreviewConfig { | |||
| 1383 | + | ret := _mock.Called() | |||
| 1384 | + | ||||
| 1385 | + | if len(ret) == 0 { | |||
| 1386 | + | panic("no return value specified for GetPreviewConfig") | |||
| 1387 | + | } | |||
| 1388 | + | ||||
| 1389 | + | var r0 domain.PreviewConfig | |||
| 1390 | + | if returnFunc, ok := ret.Get(0).(func() domain.PreviewConfig); ok { | |||
| 1391 | + | r0 = returnFunc() | |||
| 1392 | + | } else { | |||
| 1393 | + | r0 = ret.Get(0).(domain.PreviewConfig) | |||
| 1394 | + | } | |||
| 1395 | + | return r0 | |||
| 1396 | + | } | |||
| 1397 | + | ||||
| 1398 | + | // MockConfigService_GetPreviewConfig_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPreviewConfig' | |||
| 1399 | + | type MockConfigService_GetPreviewConfig_Call struct { | |||
| 1400 | + | *mock.Call | |||
| 1401 | + | } | |||
| 1402 | + | ||||
| 1403 | + | // GetPreviewConfig is a helper method to define mock.On call | |||
| 1404 | + | func (_e *MockConfigService_Expecter) GetPreviewConfig() *MockConfigService_GetPreviewConfig_Call { | |||
| 1405 | + | return &MockConfigService_GetPreviewConfig_Call{Call: _e.mock.On("GetPreviewConfig")} | |||
| 1406 | + | } | |||
| 1407 | + | ||||
| 1408 | + | func (_c *MockConfigService_GetPreviewConfig_Call) Run(run func()) *MockConfigService_GetPreviewConfig_Call { | |||
| 1409 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1410 | + | run() | |||
| 1411 | + | }) | |||
| 1412 | + | return _c | |||
| 1413 | + | } | |||
| 1414 | + | ||||
| 1415 | + | func (_c *MockConfigService_GetPreviewConfig_Call) Return(cfg domain.PreviewConfig) *MockConfigService_GetPreviewConfig_Call { | |||
| 1416 | + | _c.Call.Return(cfg) | |||
| 1417 | + | return _c | |||
| 1418 | + | } | |||
| 1419 | + | ||||
| 1420 | + | func (_c *MockConfigService_GetPreviewConfig_Call) RunAndReturn(run func() domain.PreviewConfig) *MockConfigService_GetPreviewConfig_Call { | |||
| 1421 | + | _c.Call.Return(run) | |||
| 1422 | + | return _c | |||
| 1423 | + | } | |||
| 1424 | + | ||||
| 1425 | + | // IsPreviewEnabled provides a mock function for the type MockConfigService | |||
| 1426 | + | func (_mock *MockConfigService) IsPreviewEnabled() bool { | |||
| 1427 | + | ret := _mock.Called() | |||
| 1428 | + | ||||
| 1429 | + | if len(ret) == 0 { | |||
| 1430 | + | panic("no return value specified for IsPreviewEnabled") | |||
| 1431 | + | } | |||
| 1432 | + | ||||
| 1433 | + | var r0 bool | |||
| 1434 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |||
| 1435 | + | r0 = returnFunc() | |||
| 1436 | + | } else { | |||
| 1437 | + | r0 = ret.Get(0).(bool) | |||
| 1438 | + | } | |||
| 1439 | + | return r0 | |||
| 1440 | + | } | |||
| 1441 | + | ||||
| 1442 | + | // MockConfigService_IsPreviewEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsPreviewEnabled' | |||
| 1443 | + | type MockConfigService_IsPreviewEnabled_Call struct { | |||
| 1444 | + | *mock.Call | |||
| 1445 | + | } | |||
| 1446 | + | ||||
| 1447 | + | // IsPreviewEnabled is a helper method to define mock.On call | |||
| 1448 | + | func (_e *MockConfigService_Expecter) IsPreviewEnabled() *MockConfigService_IsPreviewEnabled_Call { | |||
| 1449 | + | return &MockConfigService_IsPreviewEnabled_Call{Call: _e.mock.On("IsPreviewEnabled")} | |||
| 1450 | + | } | |||
| 1451 | + | ||||
| 1452 | + | func (_c *MockConfigService_IsPreviewEnabled_Call) Run(run func()) *MockConfigService_IsPreviewEnabled_Call { | |||
| 1453 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1454 | + | run() | |||
| 1455 | + | }) | |||
| 1456 | + | return _c | |||
| 1457 | + | } | |||
| 1458 | + | ||||
| 1459 | + | func (_c *MockConfigService_IsPreviewEnabled_Call) Return(b bool) *MockConfigService_IsPreviewEnabled_Call { | |||
| 1460 | + | _c.Call.Return(b) | |||
| 1461 | + | return _c | |||
| 1462 | + | } | |||
| 1463 | + | ||||
| 1464 | + | func (_c *MockConfigService_IsPreviewEnabled_Call) RunAndReturn(run func() bool) *MockConfigService_IsPreviewEnabled_Call { | |||
| 1465 | + | _c.Call.Return(run) | |||
| 1466 | + | return _c | |||
| 1467 | + | } | |||
| 1468 | + | ||||
| 1469 | + | // IsAutoEnabled provides a mock function for the type MockConfigService | |||
| 1470 | + | func (_mock *MockConfigService) IsAutoEnabled() bool { | |||
| 1471 | + | ret := _mock.Called() | |||
| 1472 | + | ||||
| 1473 | + | if len(ret) == 0 { | |||
| 1474 | + | panic("no return value specified for IsAutoEnabled") | |||
| 1475 | + | } | |||
| 1476 | + | ||||
| 1477 | + | var r0 bool | |||
| 1478 | + | if returnFunc, ok := ret.Get(0).(func() bool); ok { | |||
| 1479 | + | r0 = returnFunc() | |||
| 1480 | + | } else { | |||
| 1481 | + | r0 = ret.Get(0).(bool) | |||
| 1482 | + | } | |||
| 1483 | + | return r0 | |||
| 1484 | + | } | |||
| 1485 | + | ||||
| 1486 | + | // MockConfigService_IsAutoEnabled_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsAutoEnabled' | |||
| 1487 | + | type MockConfigService_IsAutoEnabled_Call struct { | |||
| 1488 | + | *mock.Call | |||
| 1489 | + | } | |||
| 1490 | + | ||||
| 1491 | + | // IsAutoEnabled is a helper method to define mock.On call | |||
| 1492 | + | func (_e *MockConfigService_Expecter) IsAutoEnabled() *MockConfigService_IsAutoEnabled_Call { | |||
| 1493 | + | return &MockConfigService_IsAutoEnabled_Call{Call: _e.mock.On("IsAutoEnabled")} | |||
| 1494 | + | } | |||
| 1495 | + | ||||
| 1496 | + | func (_c *MockConfigService_IsAutoEnabled_Call) Run(run func()) *MockConfigService_IsAutoEnabled_Call { | |||
| 1497 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1498 | + | run() | |||
| 1499 | + | }) | |||
| 1500 | + | return _c | |||
| 1501 | + | } | |||
| 1502 | + | ||||
| 1503 | + | func (_c *MockConfigService_IsAutoEnabled_Call) Return(b bool) *MockConfigService_IsAutoEnabled_Call { | |||
| 1504 | + | _c.Call.Return(b) | |||
| 1505 | + | return _c | |||
| 1506 | + | } | |||
| 1507 | + | ||||
| 1508 | + | func (_c *MockConfigService_IsAutoEnabled_Call) RunAndReturn(run func() bool) *MockConfigService_IsAutoEnabled_Call { | |||
| 1509 | + | _c.Call.Return(run) | |||
| 1510 | + | return _c | |||
| 1511 | + | } | |||
| 1512 | + | ||||
| 1513 | + | // GetPreviewTagPatterns provides a mock function for the type MockConfigService | |||
| 1514 | + | func (_mock *MockConfigService) GetPreviewTagPatterns() []string { | |||
| 1515 | + | ret := _mock.Called() | |||
| 1516 | + | ||||
| 1517 | + | if len(ret) == 0 { | |||
| 1518 | + | panic("no return value specified for GetPreviewTagPatterns") | |||
| 1519 | + | } | |||
| 1520 | + | ||||
| 1521 | + | var r0 []string | |||
| 1522 | + | if returnFunc, ok := ret.Get(0).(func() []string); ok { | |||
| 1523 | + | r0 = returnFunc() | |||
| 1524 | + | } else { | |||
| 1525 | + | if ret.Get(0) != nil { | |||
| 1526 | + | r0 = ret.Get(0).([]string) | |||
| 1527 | + | } | |||
| 1528 | + | } | |||
| 1529 | + | return r0 | |||
| 1530 | + | } | |||
| 1531 | + | ||||
| 1532 | + | // MockConfigService_GetPreviewTagPatterns_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetPreviewTagPatterns' | |||
| 1533 | + | type MockConfigService_GetPreviewTagPatterns_Call struct { | |||
| 1534 | + | *mock.Call | |||
| 1535 | + | } | |||
| 1536 | + | ||||
| 1537 | + | // GetPreviewTagPatterns is a helper method to define mock.On call | |||
| 1538 | + | func (_e *MockConfigService_Expecter) GetPreviewTagPatterns() *MockConfigService_GetPreviewTagPatterns_Call { | |||
| 1539 | + | return &MockConfigService_GetPreviewTagPatterns_Call{Call: _e.mock.On("GetPreviewTagPatterns")} | |||
| 1540 | + | } | |||
| 1541 | + | ||||
| 1542 | + | func (_c *MockConfigService_GetPreviewTagPatterns_Call) Run(run func()) *MockConfigService_GetPreviewTagPatterns_Call { | |||
| 1543 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1544 | + | run() | |||
| 1545 | + | }) | |||
| 1546 | + | return _c | |||
| 1547 | + | } | |||
| 1548 | + | ||||
| 1549 | + | func (_c *MockConfigService_GetPreviewTagPatterns_Call) Return(patterns []string) *MockConfigService_GetPreviewTagPatterns_Call { | |||
| 1550 | + | _c.Call.Return(patterns) | |||
| 1551 | + | return _c | |||
| 1552 | + | } | |||
| 1553 | + | ||||
| 1554 | + | func (_c *MockConfigService_GetPreviewTagPatterns_Call) RunAndReturn(run func() []string) *MockConfigService_GetPreviewTagPatterns_Call { | |||
| 1555 | + | _c.Call.Return(run) | |||
| 1556 | + | return _c | |||
| 1557 | + | } | |||
| 1558 | + | ||||
| 1559 | + | // GetAllowedDomains provides a mock function for the type MockConfigService | |||
| 1560 | + | func (_mock *MockConfigService) GetAllowedDomains() []string { | |||
| 1561 | + | ret := _mock.Called() | |||
| 1562 | + | ||||
| 1563 | + | if len(ret) == 0 { | |||
| 1564 | + | panic("no return value specified for GetAllowedDomains") | |||
| 1565 | + | } | |||
| 1566 | + | ||||
| 1567 | + | var r0 []string | |||
| 1568 | + | if returnFunc, ok := ret.Get(0).(func() []string); ok { | |||
| 1569 | + | r0 = returnFunc() | |||
| 1570 | + | } else { | |||
| 1571 | + | if ret.Get(0) != nil { | |||
| 1572 | + | r0 = ret.Get(0).([]string) | |||
| 1573 | + | } | |||
| 1574 | + | } | |||
| 1575 | + | return r0 | |||
| 1576 | + | } | |||
| 1577 | + | ||||
| 1578 | + | // MockConfigService_GetAllowedDomains_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetAllowedDomains' | |||
| 1579 | + | type MockConfigService_GetAllowedDomains_Call struct { | |||
| 1580 | + | *mock.Call | |||
| 1581 | + | } | |||
| 1582 | + | ||||
| 1583 | + | // GetAllowedDomains is a helper method to define mock.On call | |||
| 1584 | + | func (_e *MockConfigService_Expecter) GetAllowedDomains() *MockConfigService_GetAllowedDomains_Call { | |||
| 1585 | + | return &MockConfigService_GetAllowedDomains_Call{Call: _e.mock.On("GetAllowedDomains")} | |||
| 1586 | + | } | |||
| 1587 | + | ||||
| 1588 | + | func (_c *MockConfigService_GetAllowedDomains_Call) Run(run func()) *MockConfigService_GetAllowedDomains_Call { | |||
| 1589 | + | _c.Call.Run(func(args mock.Arguments) { | |||
| 1590 | + | run() | |||
| 1591 | + | }) | |||
| 1592 | + | return _c | |||
| 1593 | + | } | |||
| 1594 | + | ||||
| 1595 | + | func (_c *MockConfigService_GetAllowedDomains_Call) Return(domains []string) *MockConfigService_GetAllowedDomains_Call { | |||
| 1596 | + | _c.Call.Return(domains) | |||
| 1597 | + | return _c | |||
| 1598 | + | } | |||
| 1599 | + | ||||
| 1600 | + | func (_c *MockConfigService_GetAllowedDomains_Call) RunAndReturn(run func() []string) *MockConfigService_GetAllowedDomains_Call { | |||
| 1601 | + | _c.Call.Return(run) | |||
| 1602 | + | return _c | |||
| 1603 | + | } | |||
| 1604 | + | ||||
| 1381 | // Watch provides a mock function for the type MockConfigService | 1605 | // Watch provides a mock function for the type MockConfigService | ||
| 1382 | func (_mock *MockConfigService) Watch(ctx context.Context, onChange func()) error { | 1606 | func (_mock *MockConfigService) Watch(ctx context.Context, onChange func()) error { | ||
| 1383 | ret := _mock.Called(ctx, onChange) | 1607 | ret := _mock.Called(ctx, onChange) | ||
M internal/usecase/config/service.go +83 -4
| @@ -33,6 +33,11 @@ type Config struct { | |||
| 33 | 33 | DataDir string | |
| 34 | 34 | AutoRouteEnabled bool | |
| 35 | 35 | AutoRouteAllowedDomains []string `mapstructure:"auto_route_allowed_domains" json:"auto_route_allowed_domains,omitempty"` | |
| 36 | + | PreviewEnabled bool | |
| 37 | + | PreviewTTL time.Duration | |
| 38 | + | PreviewSeparator string | |
| 39 | + | PreviewTagPatterns []string | |
| 40 | + | PreviewDataCopy bool | |
| 36 | 41 | NetworkIsolation bool | |
| 37 | 42 | NetworkPrefix string | |
| 38 | 43 | Routes map[string]string | |
| @@ -122,13 +127,39 @@ func (s *Service) loadConfigValues() Config { | |||
| 122 | 127 | registryDomain = s.viper.GetString("server.registry_domain") | |
| 123 | 128 | } | |
| 124 | 129 | ||
| 130 | + | // Backward compat: try new keys first, fall back to old | |
| 131 | + | autoEnabled := s.viper.GetBool("auto.enabled") | |
| 132 | + | if !autoEnabled { | |
| 133 | + | autoEnabled = s.viper.GetBool("auto_route.enabled") | |
| 134 | + | } | |
| 135 | + | allowedDomains := s.viper.GetStringSlice("auto.allowed_domains") | |
| 136 | + | if len(allowedDomains) == 0 { | |
| 137 | + | allowedDomains = s.viper.GetStringSlice("auto_route_allowed_domains") | |
| 138 | + | } | |
| 139 | + | ||
| 140 | + | // Preview config | |
| 141 | + | previewTTLStr := s.viper.GetString("auto.preview.ttl") | |
| 142 | + | previewTTL, _ := time.ParseDuration(previewTTLStr) | |
| 143 | + | if previewTTL == 0 { | |
| 144 | + | previewTTL = 48 * time.Hour | |
| 145 | + | } | |
| 146 | + | previewSep := s.viper.GetString("auto.preview.separator") | |
| 147 | + | if previewSep == "" { | |
| 148 | + | previewSep = "--" | |
| 149 | + | } | |
| 150 | + | ||
| 125 | 151 | return Config{ | |
| 126 | 152 | ServerPort: s.viper.GetInt("server.port"), | |
| 127 | 153 | RegistryPort: s.viper.GetInt("server.registry_port"), | |
| 128 | 154 | RegistryDomain: registryDomain, | |
| 129 | 155 | DataDir: s.viper.GetString("server.data_dir"), | |
| 130 | - | AutoRouteEnabled: s.viper.GetBool("auto_route.enabled"), | |
| 131 | - | AutoRouteAllowedDomains: append([]string{}, s.viper.GetStringSlice("auto_route_allowed_domains")...), | |
| 156 | + | AutoRouteEnabled: autoEnabled, | |
| 157 | + | AutoRouteAllowedDomains: append([]string{}, allowedDomains...), | |
| 158 | + | PreviewEnabled: s.viper.GetBool("auto.preview.enabled"), | |
| 159 | + | PreviewTTL: previewTTL, | |
| 160 | + | PreviewSeparator: previewSep, | |
| 161 | + | PreviewTagPatterns: append([]string{}, s.viper.GetStringSlice("auto.preview.tag_patterns")...), | |
| 162 | + | PreviewDataCopy: s.viper.GetBool("auto.preview.data_copy"), | |
| 132 | 163 | NetworkIsolation: s.viper.GetBool("network_isolation.enabled"), | |
| 133 | 164 | NetworkPrefix: s.viper.GetString("network_isolation.network_prefix"), | |
| 134 | 165 | RegistryAuthEnabled: s.viper.GetBool("auth.enabled"), | |
| @@ -519,7 +550,7 @@ type configSnapshot struct { | |||
| 519 | 550 | } | |
| 520 | 551 | ||
| 521 | 552 | // mutableSections lists config sections that are intentionally modified by service operations. | |
| 522 | - | var mutableSections = []string{"routes.", "external_routes.", "attachments.", "network_groups.", "auto_route_allowed_domains"} | |
| 553 | + | var mutableSections = []string{"routes.", "external_routes.", "attachments.", "network_groups.", "auto_route_allowed_domains", "auto."} | |
| 523 | 554 | ||
| 524 | 555 | func isMutableKey(key string) bool { | |
| 525 | 556 | for _, prefix := range mutableSections { | |
| @@ -529,7 +560,7 @@ func isMutableKey(key string) bool { | |||
| 529 | 560 | } | |
| 530 | 561 | ||
| 531 | 562 | switch key { | |
| 532 | - | case "routes", "external_routes", "attachments", "network_groups", "auto_route_allowed_domains": | |
| 563 | + | case "routes", "external_routes", "attachments", "network_groups", "auto_route_allowed_domains", "auto": | |
| 533 | 564 | return true | |
| 534 | 565 | } | |
| 535 | 566 | ||
| @@ -570,6 +601,7 @@ func (s *Service) writeConfigSurgical(configFile string) error { | |||
| 570 | 601 | s.viper.Set("attachments", s.config.Attachments) | |
| 571 | 602 | s.viper.Set("network_groups", s.config.NetworkGroups) | |
| 572 | 603 | s.viper.Set("auto_route_allowed_domains", s.config.AutoRouteAllowedDomains) | |
| 604 | + | s.viper.Set("auto.allowed_domains", s.config.AutoRouteAllowedDomains) | |
| 573 | 605 | return s.viper.WriteConfigAs(configFile) | |
| 574 | 606 | } | |
| 575 | 607 | return fmt.Errorf("failed to read config file: %w", err) | |
| @@ -589,7 +621,15 @@ func (s *Service) writeConfigSurgical(configFile string) error { | |||
| 589 | 621 | config["external_routes"] = s.config.ExternalRoutes | |
| 590 | 622 | config["attachments"] = s.config.Attachments | |
| 591 | 623 | config["network_groups"] = s.config.NetworkGroups | |
| 624 | + | // Write to both old and new keys for backward compat | |
| 592 | 625 | config["auto_route_allowed_domains"] = s.config.AutoRouteAllowedDomains | |
| 626 | + | if autoSection, ok := config["auto"].(map[string]any); ok { | |
| 627 | + | autoSection["allowed_domains"] = s.config.AutoRouteAllowedDomains | |
| 628 | + | } else { | |
| 629 | + | config["auto"] = map[string]any{ | |
| 630 | + | "allowed_domains": s.config.AutoRouteAllowedDomains, | |
| 631 | + | } | |
| 632 | + | } | |
| 593 | 633 | ||
| 594 | 634 | out, err := toml.Marshal(config) | |
| 595 | 635 | if err != nil { | |
| @@ -1050,6 +1090,45 @@ func (s *Service) RemoveAttachment(ctx context.Context, domainOrGroup, image str | |||
| 1050 | 1090 | return nil | |
| 1051 | 1091 | } | |
| 1052 | 1092 | ||
| 1093 | + | // GetPreviewConfig returns the preview environment configuration. | |
| 1094 | + | func (s *Service) GetPreviewConfig() domain.PreviewConfig { | |
| 1095 | + | s.mu.RLock() | |
| 1096 | + | defer s.mu.RUnlock() | |
| 1097 | + | return domain.PreviewConfig{ | |
| 1098 | + | Enabled: s.config.PreviewEnabled, | |
| 1099 | + | TTL: s.config.PreviewTTL, | |
| 1100 | + | Separator: s.config.PreviewSeparator, | |
| 1101 | + | TagPatterns: s.config.PreviewTagPatterns, | |
| 1102 | + | DataCopy: s.config.PreviewDataCopy, | |
| 1103 | + | } | |
| 1104 | + | } | |
| 1105 | + | ||
| 1106 | + | // IsPreviewEnabled returns whether preview environments are enabled. | |
| 1107 | + | func (s *Service) IsPreviewEnabled() bool { | |
| 1108 | + | s.mu.RLock() | |
| 1109 | + | defer s.mu.RUnlock() | |
| 1110 | + | return s.config.PreviewEnabled | |
| 1111 | + | } | |
| 1112 | + | ||
| 1113 | + | // IsAutoEnabled returns whether the auto feature is enabled (alias for IsAutoRouteEnabled). | |
| 1114 | + | func (s *Service) IsAutoEnabled() bool { | |
| 1115 | + | return s.IsAutoRouteEnabled() | |
| 1116 | + | } | |
| 1117 | + | ||
| 1118 | + | // GetPreviewTagPatterns returns the configured tag patterns for preview environments. | |
| 1119 | + | func (s *Service) GetPreviewTagPatterns() []string { | |
| 1120 | + | s.mu.RLock() | |
| 1121 | + | defer s.mu.RUnlock() | |
| 1122 | + | return append([]string{}, s.config.PreviewTagPatterns...) | |
| 1123 | + | } | |
| 1124 | + | ||
| 1125 | + | // GetAllowedDomains returns the auto-route allowed domain patterns. | |
| 1126 | + | func (s *Service) GetAllowedDomains() []string { | |
| 1127 | + | s.mu.RLock() | |
| 1128 | + | defer s.mu.RUnlock() | |
| 1129 | + | return append([]string{}, s.config.AutoRouteAllowedDomains...) | |
| 1130 | + | } | |
| 1131 | + | ||
| 1053 | 1132 | // GetAutoRouteAllowedDomains returns the configured auto-route domain allowlist. | |
| 1054 | 1133 | func (s *Service) GetAutoRouteAllowedDomains(_ context.Context) ([]string, error) { | |
| 1055 | 1134 | s.mu.RLock() | |
| @@ -33,6 +33,11 @@ type Config struct { | |||||
| 33 | DataDir string | 33 | DataDir string | ||
| 34 | AutoRouteEnabled bool | 34 | AutoRouteEnabled bool | ||
| 35 | AutoRouteAllowedDomains []string `mapstructure:"auto_route_allowed_domains" json:"auto_route_allowed_domains,omitempty"` | 35 | AutoRouteAllowedDomains []string `mapstructure:"auto_route_allowed_domains" json:"auto_route_allowed_domains,omitempty"` | ||
| 36 | + | PreviewEnabled bool | |||
| 37 | + | PreviewTTL time.Duration | |||
| 38 | + | PreviewSeparator string | |||
| 39 | + | PreviewTagPatterns []string | |||
| 40 | + | PreviewDataCopy bool | |||
| 36 | NetworkIsolation bool | 41 | NetworkIsolation bool | ||
| 37 | NetworkPrefix string | 42 | NetworkPrefix string | ||
| 38 | Routes map[string]string | 43 | Routes map[string]string | ||
| @@ -122,13 +127,39 @@ func (s *Service) loadConfigValues() Config { | |||||
| 122 | registryDomain = s.viper.GetString("server.registry_domain") | 127 | registryDomain = s.viper.GetString("server.registry_domain") | ||
| 123 | } | 128 | } | ||
| 124 | 129 | ||||
| 130 | + | // Backward compat: try new keys first, fall back to old | |||
| 131 | + | autoEnabled := s.viper.GetBool("auto.enabled") | |||
| 132 | + | if !autoEnabled { | |||
| 133 | + | autoEnabled = s.viper.GetBool("auto_route.enabled") | |||
| 134 | + | } | |||
| 135 | + | allowedDomains := s.viper.GetStringSlice("auto.allowed_domains") | |||
| 136 | + | if len(allowedDomains) == 0 { | |||
| 137 | + | allowedDomains = s.viper.GetStringSlice("auto_route_allowed_domains") | |||
| 138 | + | } | |||
| 139 | + | ||||
| 140 | + | // Preview config | |||
| 141 | + | previewTTLStr := s.viper.GetString("auto.preview.ttl") | |||
| 142 | + | previewTTL, _ := time.ParseDuration(previewTTLStr) | |||
| 143 | + | if previewTTL == 0 { | |||
| 144 | + | previewTTL = 48 * time.Hour | |||
| 145 | + | } | |||
| 146 | + | previewSep := s.viper.GetString("auto.preview.separator") | |||
| 147 | + | if previewSep == "" { | |||
| 148 | + | previewSep = "--" | |||
| 149 | + | } | |||
| 150 | + | ||||
| 125 | return Config{ | 151 | return Config{ | ||
| 126 | ServerPort: s.viper.GetInt("server.port"), | 152 | ServerPort: s.viper.GetInt("server.port"), | ||
| 127 | RegistryPort: s.viper.GetInt("server.registry_port"), | 153 | RegistryPort: s.viper.GetInt("server.registry_port"), | ||
| 128 | RegistryDomain: registryDomain, | 154 | RegistryDomain: registryDomain, | ||
| 129 | DataDir: s.viper.GetString("server.data_dir"), | 155 | DataDir: s.viper.GetString("server.data_dir"), | ||
| 130 | - | AutoRouteEnabled: s.viper.GetBool("auto_route.enabled"), | 156 | + | AutoRouteEnabled: autoEnabled, |
| 131 | - | AutoRouteAllowedDomains: append([]string{}, s.viper.GetStringSlice("auto_route_allowed_domains")...), | 157 | + | AutoRouteAllowedDomains: append([]string{}, allowedDomains...), |
| 158 | + | PreviewEnabled: s.viper.GetBool("auto.preview.enabled"), | |||
| 159 | + | PreviewTTL: previewTTL, | |||
| 160 | + | PreviewSeparator: previewSep, | |||
| 161 | + | PreviewTagPatterns: append([]string{}, s.viper.GetStringSlice("auto.preview.tag_patterns")...), | |||
| 162 | + | PreviewDataCopy: s.viper.GetBool("auto.preview.data_copy"), | |||
| 132 | NetworkIsolation: s.viper.GetBool("network_isolation.enabled"), | 163 | NetworkIsolation: s.viper.GetBool("network_isolation.enabled"), | ||
| 133 | NetworkPrefix: s.viper.GetString("network_isolation.network_prefix"), | 164 | NetworkPrefix: s.viper.GetString("network_isolation.network_prefix"), | ||
| 134 | RegistryAuthEnabled: s.viper.GetBool("auth.enabled"), | 165 | RegistryAuthEnabled: s.viper.GetBool("auth.enabled"), | ||
| @@ -519,7 +550,7 @@ type configSnapshot struct { | |||||
| 519 | } | 550 | } | ||
| 520 | 551 | ||||
| 521 | // mutableSections lists config sections that are intentionally modified by service operations. | 552 | // mutableSections lists config sections that are intentionally modified by service operations. | ||
| 522 | - | var mutableSections = []string{"routes.", "external_routes.", "attachments.", "network_groups.", "auto_route_allowed_domains"} | 553 | + | var mutableSections = []string{"routes.", "external_routes.", "attachments.", "network_groups.", "auto_route_allowed_domains", "auto."} |
| 523 | 554 | ||||
| 524 | func isMutableKey(key string) bool { | 555 | func isMutableKey(key string) bool { | ||
| 525 | for _, prefix := range mutableSections { | 556 | for _, prefix := range mutableSections { | ||
| @@ -529,7 +560,7 @@ func isMutableKey(key string) bool { | |||||
| 529 | } | 560 | } | ||
| 530 | 561 | ||||
| 531 | switch key { | 562 | switch key { | ||
| 532 | - | case "routes", "external_routes", "attachments", "network_groups", "auto_route_allowed_domains": | 563 | + | case "routes", "external_routes", "attachments", "network_groups", "auto_route_allowed_domains", "auto": |
| 533 | return true | 564 | return true | ||
| 534 | } | 565 | } | ||
| 535 | 566 | ||||
| @@ -570,6 +601,7 @@ func (s *Service) writeConfigSurgical(configFile string) error { | |||||
| 570 | s.viper.Set("attachments", s.config.Attachments) | 601 | s.viper.Set("attachments", s.config.Attachments) | ||
| 571 | s.viper.Set("network_groups", s.config.NetworkGroups) | 602 | s.viper.Set("network_groups", s.config.NetworkGroups) | ||
| 572 | s.viper.Set("auto_route_allowed_domains", s.config.AutoRouteAllowedDomains) | 603 | s.viper.Set("auto_route_allowed_domains", s.config.AutoRouteAllowedDomains) | ||
| 604 | + | s.viper.Set("auto.allowed_domains", s.config.AutoRouteAllowedDomains) | |||
| 573 | return s.viper.WriteConfigAs(configFile) | 605 | return s.viper.WriteConfigAs(configFile) | ||
| 574 | } | 606 | } | ||
| 575 | return fmt.Errorf("failed to read config file: %w", err) | 607 | return fmt.Errorf("failed to read config file: %w", err) | ||
| @@ -589,7 +621,15 @@ func (s *Service) writeConfigSurgical(configFile string) error { | |||||
| 589 | config["external_routes"] = s.config.ExternalRoutes | 621 | config["external_routes"] = s.config.ExternalRoutes | ||
| 590 | config["attachments"] = s.config.Attachments | 622 | config["attachments"] = s.config.Attachments | ||
| 591 | config["network_groups"] = s.config.NetworkGroups | 623 | config["network_groups"] = s.config.NetworkGroups | ||
| 624 | + | // Write to both old and new keys for backward compat | |||
| 592 | config["auto_route_allowed_domains"] = s.config.AutoRouteAllowedDomains | 625 | config["auto_route_allowed_domains"] = s.config.AutoRouteAllowedDomains | ||
| 626 | + | if autoSection, ok := config["auto"].(map[string]any); ok { | |||
| 627 | + | autoSection["allowed_domains"] = s.config.AutoRouteAllowedDomains | |||
| 628 | + | } else { | |||
| 629 | + | config["auto"] = map[string]any{ | |||
| 630 | + | "allowed_domains": s.config.AutoRouteAllowedDomains, | |||
| 631 | + | } | |||
| 632 | + | } | |||
| 593 | 633 | ||||
| 594 | out, err := toml.Marshal(config) | 634 | out, err := toml.Marshal(config) | ||
| 595 | if err != nil { | 635 | if err != nil { | ||
| @@ -1050,6 +1090,45 @@ func (s *Service) RemoveAttachment(ctx context.Context, domainOrGroup, image str | |||||
| 1050 | return nil | 1090 | return nil | ||
| 1051 | } | 1091 | } | ||
| 1052 | 1092 | ||||
| 1093 | + | // GetPreviewConfig returns the preview environment configuration. | |||
| 1094 | + | func (s *Service) GetPreviewConfig() domain.PreviewConfig { | |||
| 1095 | + | s.mu.RLock() | |||
| 1096 | + | defer s.mu.RUnlock() | |||
| 1097 | + | return domain.PreviewConfig{ | |||
| 1098 | + | Enabled: s.config.PreviewEnabled, | |||
| 1099 | + | TTL: s.config.PreviewTTL, | |||
| 1100 | + | Separator: s.config.PreviewSeparator, | |||
| 1101 | + | TagPatterns: s.config.PreviewTagPatterns, | |||
| 1102 | + | DataCopy: s.config.PreviewDataCopy, | |||
| 1103 | + | } | |||
| 1104 | + | } | |||
| 1105 | + | ||||
| 1106 | + | // IsPreviewEnabled returns whether preview environments are enabled. | |||
| 1107 | + | func (s *Service) IsPreviewEnabled() bool { | |||
| 1108 | + | s.mu.RLock() | |||
| 1109 | + | defer s.mu.RUnlock() | |||
| 1110 | + | return s.config.PreviewEnabled | |||
| 1111 | + | } | |||
| 1112 | + | ||||
| 1113 | + | // IsAutoEnabled returns whether the auto feature is enabled (alias for IsAutoRouteEnabled). | |||
| 1114 | + | func (s *Service) IsAutoEnabled() bool { | |||
| 1115 | + | return s.IsAutoRouteEnabled() | |||
| 1116 | + | } | |||
| 1117 | + | ||||
| 1118 | + | // GetPreviewTagPatterns returns the configured tag patterns for preview environments. | |||
| 1119 | + | func (s *Service) GetPreviewTagPatterns() []string { | |||
| 1120 | + | s.mu.RLock() | |||
| 1121 | + | defer s.mu.RUnlock() | |||
| 1122 | + | return append([]string{}, s.config.PreviewTagPatterns...) | |||
| 1123 | + | } | |||
| 1124 | + | ||||
| 1125 | + | // GetAllowedDomains returns the auto-route allowed domain patterns. | |||
| 1126 | + | func (s *Service) GetAllowedDomains() []string { | |||
| 1127 | + | s.mu.RLock() | |||
| 1128 | + | defer s.mu.RUnlock() | |||
| 1129 | + | return append([]string{}, s.config.AutoRouteAllowedDomains...) | |||
| 1130 | + | } | |||
| 1131 | + | ||||
| 1053 | // GetAutoRouteAllowedDomains returns the configured auto-route domain allowlist. | 1132 | // GetAutoRouteAllowedDomains returns the configured auto-route domain allowlist. | ||
| 1054 | func (s *Service) GetAutoRouteAllowedDomains(_ context.Context) ([]string, error) { | 1133 | func (s *Service) GetAutoRouteAllowedDomains(_ context.Context) ([]string, error) { | ||
| 1055 | s.mu.RLock() | 1134 | s.mu.RLock() | ||