@jskit-ai/google-rewarded-core 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +98 -0
  2. package/docs/protecting-server-actions.md +190 -0
  3. package/package.descriptor.mjs +186 -0
  4. package/package.json +10 -0
  5. package/src/server/GoogleRewardedCoreProvider.js +51 -0
  6. package/src/server/actions.js +102 -0
  7. package/src/server/inputSchemas.js +394 -0
  8. package/src/server/providerConfigs/GoogleRewardedProviderConfigsProvider.js +98 -0
  9. package/src/server/providerConfigs/actions.js +157 -0
  10. package/src/server/providerConfigs/registerRoutes.js +176 -0
  11. package/src/server/providerConfigs/repository.js +107 -0
  12. package/src/server/providerConfigs/service.js +61 -0
  13. package/src/server/registerRoutes.js +169 -0
  14. package/src/server/rules/GoogleRewardedRulesProvider.js +98 -0
  15. package/src/server/rules/actions.js +157 -0
  16. package/src/server/rules/registerRoutes.js +176 -0
  17. package/src/server/rules/repository.js +107 -0
  18. package/src/server/rules/service.js +61 -0
  19. package/src/server/service.js +552 -0
  20. package/src/server/support/requireGoogleRewardedUnlock.js +142 -0
  21. package/src/server/unlockReceipts/GoogleRewardedUnlockReceiptsProvider.js +98 -0
  22. package/src/server/unlockReceipts/actions.js +157 -0
  23. package/src/server/unlockReceipts/registerRoutes.js +176 -0
  24. package/src/server/unlockReceipts/repository.js +107 -0
  25. package/src/server/unlockReceipts/service.js +61 -0
  26. package/src/server/watchSessions/GoogleRewardedWatchSessionsProvider.js +98 -0
  27. package/src/server/watchSessions/actions.js +157 -0
  28. package/src/server/watchSessions/registerRoutes.js +176 -0
  29. package/src/server/watchSessions/repository.js +107 -0
  30. package/src/server/watchSessions/service.js +61 -0
  31. package/src/shared/googleRewardedProviderConfigResource.js +94 -0
  32. package/src/shared/googleRewardedRuleResource.js +136 -0
  33. package/src/shared/googleRewardedUnlockReceiptResource.js +113 -0
  34. package/src/shared/googleRewardedWatchSessionResource.js +139 -0
  35. package/src/shared/index.js +12 -0
  36. package/templates/migrations/google_rewarded_provider_configs_initial.cjs +27 -0
  37. package/templates/migrations/google_rewarded_rules_initial.cjs +31 -0
  38. package/templates/migrations/google_rewarded_unlock_receipts_initial.cjs +35 -0
  39. package/templates/migrations/google_rewarded_watch_sessions_initial.cjs +36 -0
  40. package/test/requireGoogleRewardedUnlock.test.js +274 -0
  41. package/test/routes.test.js +248 -0
  42. package/test/service.test.js +315 -0
package/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # @jskit-ai/google-rewarded-core
2
+
3
+ Server runtime for Google rewarded unlock gates.
4
+
5
+ ## Package Shape
6
+
7
+ This package installs:
8
+
9
+ - four CRUD-owned server providers, one per persisted table
10
+ - one workflow provider for the rewarded gate API
11
+
12
+ The persisted tables are:
13
+
14
+ - `google_rewarded_rules`
15
+ - `google_rewarded_provider_configs`
16
+ - `google_rewarded_watch_sessions`
17
+ - `google_rewarded_unlock_receipts`
18
+
19
+ The package keeps the CRUD ownership strict:
20
+
21
+ - rules and provider configs are `workspace`-owned
22
+ - watch sessions and unlock receipts are `workspace_user`-owned
23
+
24
+ Every owned row carries direct owner columns. The module does not rely on inherited ownership through parent joins.
25
+
26
+ ## What It Does
27
+
28
+ The workflow provider exposes four workspace-scoped app routes:
29
+
30
+ - `GET /api/w/:workspaceSlug/google-rewarded/current`
31
+ - `POST /api/w/:workspaceSlug/google-rewarded/start`
32
+ - `POST /api/w/:workspaceSlug/google-rewarded/grant`
33
+ - `POST /api/w/:workspaceSlug/google-rewarded/close`
34
+
35
+ These are plain workflow endpoints, not CRUD JSON:API endpoints.
36
+
37
+ The flow is:
38
+
39
+ 1. `current` decides whether the gate is enabled, blocked, or already unlocked.
40
+ 2. `start` creates a watch session when a reward is required.
41
+ 3. `grant` marks the session rewarded and creates an unlock receipt.
42
+ 4. `close` closes a started session without granting access.
43
+
44
+ Day 0 is intentionally app-surface-only for the rewarded workflow. Rules and provider configs should therefore use `surface = "app"` for the active gate rows.
45
+
46
+ ## Required Data
47
+
48
+ Day-0 configuration lives in the CRUD-owned tables.
49
+
50
+ At minimum, apps need:
51
+
52
+ - a `google_rewarded_rules` row for the target `gateKey`
53
+ - a matching enabled `google_rewarded_provider_configs` row for the surface
54
+
55
+ Important config fields:
56
+
57
+ - `google_rewarded_rules.gate_key`
58
+ - `google_rewarded_rules.surface`
59
+ - `google_rewarded_rules.unlock_minutes`
60
+ - `google_rewarded_rules.cooldown_minutes`
61
+ - `google_rewarded_rules.daily_limit`
62
+ - `google_rewarded_provider_configs.surface`
63
+ - `google_rewarded_provider_configs.ad_unit_path`
64
+ - `google_rewarded_provider_configs.script_mode`
65
+
66
+ Day 0 assumes GPT rewarded ads for web, so `script_mode` should stay aligned with that flow.
67
+
68
+ ## Protecting Server Features
69
+
70
+ Protected server mutations should use the exported helper:
71
+
72
+ ```js
73
+ import { requireGoogleRewardedUnlock } from "@jskit-ai/google-rewarded-core/server/requireGoogleRewardedUnlock";
74
+ ```
75
+
76
+ The dedicated manual page is:
77
+
78
+ - [docs/protecting-server-actions.md](/home/merc/Development/current/jskit-ai/packages/google-rewarded-core/docs/protecting-server-actions.md)
79
+
80
+ That page shows the exact service and provider wiring pattern.
81
+
82
+ ## Policy Model
83
+
84
+ This module is designed for rewarded unlocks, not for blocking all normal app use on boot.
85
+
86
+ Recommended usage:
87
+
88
+ - unlock bonus actions
89
+ - unlock extra quota
90
+ - unlock a temporary feature window
91
+
92
+ Do not treat it as a hard requirement for baseline product use unless the ad provider policy clearly allows that.
93
+
94
+ ## Install Notes
95
+
96
+ When an app adds this package, JSKIT installs the four schema migrations from `templates/migrations/`.
97
+
98
+ The package does not add day-0 settings pages automatically. Configuration can stay manual or be layered with app-specific UI later.
@@ -0,0 +1,190 @@
1
+ # Protecting Server Actions With `requireGoogleRewardedUnlock()`
2
+
3
+ This is the manual page for the server helper exported by:
4
+
5
+ ```js
6
+ @jskit-ai/google-rewarded-core/server/requireGoogleRewardedUnlock
7
+ ```
8
+
9
+ Use this helper when a feature is:
10
+
11
+ - allowed in principle for the actor
12
+ - but temporarily gated behind a rewarded unlock
13
+
14
+ Do not use it as a permission system.
15
+
16
+ The correct split is:
17
+
18
+ - permissions decide whether the actor may ever do the thing
19
+ - rewarded gates decide whether the actor must unlock the thing right now
20
+
21
+ ## What The Helper Does
22
+
23
+ `requireGoogleRewardedUnlock()` calls `google-rewarded.core.service.getCurrentState(...)` and then enforces one simple rule:
24
+
25
+ - if the gate is already unlocked, it returns the gate state
26
+ - if the gate is not configured and `requireConfigured` is not enabled, it returns the gate state
27
+ - otherwise it throws an `AppError`
28
+
29
+ This means the helper is a truth-enforcement seam for protected server operations.
30
+
31
+ The UI should still call the web runtime first for user experience, but the protected server operation must also check the gate so users cannot bypass it by calling the endpoint directly.
32
+
33
+ ## Import Path
34
+
35
+ ```js
36
+ import { requireGoogleRewardedUnlock } from "@jskit-ai/google-rewarded-core/server/requireGoogleRewardedUnlock";
37
+ ```
38
+
39
+ ## Basic Service Pattern
40
+
41
+ Inject `google-rewarded.core.service` into your own feature service, then call the helper before the protected mutation.
42
+
43
+ Example:
44
+
45
+ ```js
46
+ import { requireGoogleRewardedUnlock } from "@jskit-ai/google-rewarded-core/server/requireGoogleRewardedUnlock";
47
+
48
+ function createProgressLoggingService({
49
+ googleRewardedService,
50
+ workoutLogRepository
51
+ } = {}) {
52
+ async function logProgress(input = {}, options = {}) {
53
+ await requireGoogleRewardedUnlock(
54
+ googleRewardedService,
55
+ {
56
+ gateKey: "progress-logging",
57
+ workspaceSlug: input.workspaceSlug
58
+ },
59
+ {
60
+ context: options.context,
61
+ errorMessage: "Watch a rewarded ad before logging progress."
62
+ }
63
+ );
64
+
65
+ return workoutLogRepository.create(input, options);
66
+ }
67
+
68
+ return Object.freeze({
69
+ logProgress
70
+ });
71
+ }
72
+ ```
73
+
74
+ ## Provider Wiring Pattern
75
+
76
+ Inject the rewarded service from the container the same way as any other JSKIT runtime service.
77
+
78
+ Example:
79
+
80
+ ```js
81
+ app.service(
82
+ "convict.progress-logging.service",
83
+ (scope) => createProgressLoggingService({
84
+ googleRewardedService: scope.make("google-rewarded.core.service"),
85
+ workoutLogRepository: scope.make("convict.workout-log.repository")
86
+ })
87
+ );
88
+ ```
89
+
90
+ ## Exact Helper Signature
91
+
92
+ ```js
93
+ await requireGoogleRewardedUnlock(
94
+ googleRewardedService,
95
+ {
96
+ gateKey,
97
+ workspaceSlug
98
+ },
99
+ {
100
+ context,
101
+ requireConfigured,
102
+ errorCode,
103
+ errorMessage
104
+ }
105
+ );
106
+ ```
107
+
108
+ Arguments:
109
+
110
+ - `googleRewardedService`
111
+ - must expose `getCurrentState(input, { context })`
112
+ - first object
113
+ - `gateKey`: required gate identifier
114
+ - `workspaceSlug`: required for the current workspace gate
115
+ - second object
116
+ - `context`: the normal JSKIT action/service context
117
+ - `requireConfigured`: fail closed when no rule/provider config exists
118
+ - `errorCode`: optional override for the thrown `AppError.code`
119
+ - `errorMessage`: optional override for the thrown `AppError.message`
120
+
121
+ ## Default Behavior
122
+
123
+ The helper is intentionally permissive when the rewarded gate is not configured.
124
+
125
+ By default:
126
+
127
+ - `reason = "rule-not-configured"` passes
128
+ - `reason = "provider-not-configured"` passes
129
+
130
+ Why:
131
+
132
+ - day-0 apps may install the package before creating live rules/config rows
133
+ - you do not want every protected feature to break during setup or partial rollout
134
+
135
+ If you want the protected operation to fail closed until configuration exists, set:
136
+
137
+ ```js
138
+ requireConfigured: true
139
+ ```
140
+
141
+ ## When The Helper Throws
142
+
143
+ The helper throws `AppError` with `details.rewardedGate` containing the full gate state.
144
+
145
+ Important built-in failure cases:
146
+
147
+ - `reward-required`
148
+ - status: `423`
149
+ - code: `google_rewarded_unlock_required`
150
+ - `cooldown-active`
151
+ - status: `423`
152
+ - code: `google_rewarded_cooldown_active`
153
+ - `daily-limit-reached`
154
+ - status: `423`
155
+ - code: `google_rewarded_daily_limit_reached`
156
+ - `rule-not-configured` or `provider-not-configured` with `requireConfigured: true`
157
+ - status: `503`
158
+ - code: `google_rewarded_not_configured`
159
+
160
+ ## What The Helper Returns
161
+
162
+ On success, the helper returns the gate state from `googleRewardedService.getCurrentState(...)`.
163
+
164
+ That lets your service inspect the unlock window if it wants to log or branch on it, for example:
165
+
166
+ ```js
167
+ const gateState = await requireGoogleRewardedUnlock(...);
168
+ const unlockedUntil = gateState.unlock?.unlockedUntil || null;
169
+ ```
170
+
171
+ ## Recommended Calling Order
172
+
173
+ For a protected feature operation:
174
+
175
+ 1. run normal permission / ownership checks
176
+ 2. run `requireGoogleRewardedUnlock(...)`
177
+ 3. perform the real mutation
178
+
179
+ Do not invert that order.
180
+
181
+ ## What Not To Do
182
+
183
+ Do not:
184
+
185
+ - model rewarded gates as permissions
186
+ - skip the server check because the client already opened the gate
187
+ - rely on route visibility as the rewarded gate
188
+ - duplicate the raw `reason` checks in every feature service
189
+
190
+ Use the helper instead of open-coding that logic.
@@ -0,0 +1,186 @@
1
+ export default Object.freeze({
2
+ packageVersion: 1,
3
+ packageId: "@jskit-ai/google-rewarded-core",
4
+ version: "0.1.1",
5
+ kind: "runtime",
6
+ description: "Google rewarded workflow runtime plus internal CRUD providers for rules, provider configs, watch sessions, and unlock receipts.",
7
+ dependsOn: [
8
+ "@jskit-ai/auth-core",
9
+ "@jskit-ai/crud-core",
10
+ "@jskit-ai/database-runtime",
11
+ "@jskit-ai/http-runtime",
12
+ "@jskit-ai/json-rest-api-core",
13
+ "@jskit-ai/kernel",
14
+ "@jskit-ai/resource-crud-core",
15
+ "@jskit-ai/workspaces-core"
16
+ ],
17
+ capabilities: {
18
+ provides: [
19
+ "crud.google-rewarded-rules",
20
+ "crud.google-rewarded-provider-configs",
21
+ "crud.google-rewarded-watch-sessions",
22
+ "crud.google-rewarded-unlock-receipts",
23
+ "google-rewarded.core"
24
+ ],
25
+ requires: [
26
+ "runtime.actions",
27
+ "runtime.database",
28
+ "auth.policy",
29
+ "json-rest-api.core"
30
+ ]
31
+ },
32
+ runtime: {
33
+ server: {
34
+ providers: [
35
+ {
36
+ entrypoint: "src/server/rules/GoogleRewardedRulesProvider.js",
37
+ export: "GoogleRewardedRulesProvider"
38
+ },
39
+ {
40
+ entrypoint: "src/server/providerConfigs/GoogleRewardedProviderConfigsProvider.js",
41
+ export: "GoogleRewardedProviderConfigsProvider"
42
+ },
43
+ {
44
+ entrypoint: "src/server/watchSessions/GoogleRewardedWatchSessionsProvider.js",
45
+ export: "GoogleRewardedWatchSessionsProvider"
46
+ },
47
+ {
48
+ entrypoint: "src/server/unlockReceipts/GoogleRewardedUnlockReceiptsProvider.js",
49
+ export: "GoogleRewardedUnlockReceiptsProvider"
50
+ },
51
+ {
52
+ entrypoint: "src/server/GoogleRewardedCoreProvider.js",
53
+ export: "GoogleRewardedCoreProvider"
54
+ }
55
+ ]
56
+ },
57
+ client: {
58
+ providers: []
59
+ }
60
+ },
61
+ metadata: {
62
+ jskit: {
63
+ scaffoldShape: "crud-server-v1",
64
+ tableOwnership: {
65
+ tables: [
66
+ {
67
+ tableName: "google_rewarded_rules",
68
+ provenance: "crud-server-generator",
69
+ ownerKind: "crud-package",
70
+ providerEntrypoint: "src/server/rules/GoogleRewardedRulesProvider.js",
71
+ ownershipFilter: "workspace"
72
+ },
73
+ {
74
+ tableName: "google_rewarded_provider_configs",
75
+ provenance: "crud-server-generator",
76
+ ownerKind: "crud-package",
77
+ providerEntrypoint: "src/server/providerConfigs/GoogleRewardedProviderConfigsProvider.js",
78
+ ownershipFilter: "workspace"
79
+ },
80
+ {
81
+ tableName: "google_rewarded_watch_sessions",
82
+ provenance: "crud-server-generator",
83
+ ownerKind: "crud-package",
84
+ providerEntrypoint: "src/server/watchSessions/GoogleRewardedWatchSessionsProvider.js",
85
+ ownershipFilter: "workspace_user"
86
+ },
87
+ {
88
+ tableName: "google_rewarded_unlock_receipts",
89
+ provenance: "crud-server-generator",
90
+ ownerKind: "crud-package",
91
+ providerEntrypoint: "src/server/unlockReceipts/GoogleRewardedUnlockReceiptsProvider.js",
92
+ ownershipFilter: "workspace_user"
93
+ }
94
+ ]
95
+ }
96
+ },
97
+ apiSummary: {
98
+ surfaces: [
99
+ {
100
+ subpath: "./shared",
101
+ summary: "Exports Google rewarded shared CRUD resources."
102
+ },
103
+ {
104
+ subpath: "./server/actions",
105
+ summary: "Exports Google rewarded workflow action identifiers and validators."
106
+ },
107
+ {
108
+ subpath: "./server/requireGoogleRewardedUnlock",
109
+ summary: "Exports the server helper that enforces a rewarded unlock before a protected feature action continues."
110
+ }
111
+ ],
112
+ containerTokens: {
113
+ server: [
114
+ "repository.google_rewarded_rules",
115
+ "crud.google_rewarded_rules",
116
+ "repository.google_rewarded_provider_configs",
117
+ "crud.google_rewarded_provider_configs",
118
+ "repository.google_rewarded_watch_sessions",
119
+ "crud.google_rewarded_watch_sessions",
120
+ "repository.google_rewarded_unlock_receipts",
121
+ "crud.google_rewarded_unlock_receipts",
122
+ "google-rewarded.core.service"
123
+ ],
124
+ client: []
125
+ }
126
+ }
127
+ },
128
+ mutations: {
129
+ dependencies: {
130
+ runtime: {
131
+ "@jskit-ai/auth-core": "0.1.63",
132
+ "@jskit-ai/crud-core": "0.1.72",
133
+ "@jskit-ai/database-runtime": "0.1.64",
134
+ "@jskit-ai/http-runtime": "0.1.63",
135
+ "@jskit-ai/json-rest-api-core": "0.1.9",
136
+ "@jskit-ai/kernel": "0.1.64",
137
+ "@jskit-ai/resource-crud-core": "0.1.9",
138
+ "@jskit-ai/workspaces-core": "0.1.40"
139
+ },
140
+ dev: {}
141
+ },
142
+ packageJson: {
143
+ scripts: {}
144
+ },
145
+ procfile: {},
146
+ files: [
147
+ {
148
+ op: "install-migration",
149
+ from: "templates/migrations/google_rewarded_rules_initial.cjs",
150
+ toDir: "migrations",
151
+ extension: ".cjs",
152
+ reason: "Install Google rewarded rules schema migration.",
153
+ category: "google-rewarded",
154
+ id: "google-rewarded-rules-initial-schema"
155
+ },
156
+ {
157
+ op: "install-migration",
158
+ from: "templates/migrations/google_rewarded_provider_configs_initial.cjs",
159
+ toDir: "migrations",
160
+ extension: ".cjs",
161
+ reason: "Install Google rewarded provider config schema migration.",
162
+ category: "google-rewarded",
163
+ id: "google-rewarded-provider-configs-initial-schema"
164
+ },
165
+ {
166
+ op: "install-migration",
167
+ from: "templates/migrations/google_rewarded_watch_sessions_initial.cjs",
168
+ toDir: "migrations",
169
+ extension: ".cjs",
170
+ reason: "Install Google rewarded watch sessions schema migration.",
171
+ category: "google-rewarded",
172
+ id: "google-rewarded-watch-sessions-initial-schema"
173
+ },
174
+ {
175
+ op: "install-migration",
176
+ from: "templates/migrations/google_rewarded_unlock_receipts_initial.cjs",
177
+ toDir: "migrations",
178
+ extension: ".cjs",
179
+ reason: "Install Google rewarded unlock receipts schema migration.",
180
+ category: "google-rewarded",
181
+ id: "google-rewarded-unlock-receipts-initial-schema"
182
+ }
183
+ ],
184
+ text: []
185
+ }
186
+ });
package/package.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "name": "@jskit-ai/google-rewarded-core",
3
+ "version": "0.1.1",
4
+ "type": "module",
5
+ "exports": {
6
+ "./shared": "./src/shared/index.js",
7
+ "./server/actions": "./src/server/actions.js",
8
+ "./server/requireGoogleRewardedUnlock": "./src/server/support/requireGoogleRewardedUnlock.js"
9
+ }
10
+ }
@@ -0,0 +1,51 @@
1
+ import { withActionDefaults } from "@jskit-ai/kernel/shared/actions";
2
+
3
+ import { createService } from "./service.js";
4
+ import { googleRewardedActions } from "./actions.js";
5
+ import { registerRoutes } from "./registerRoutes.js";
6
+
7
+ class GoogleRewardedCoreProvider {
8
+ static id = "google-rewarded.core";
9
+
10
+ static dependsOn = ["runtime.actions"];
11
+
12
+ register(app) {
13
+ if (
14
+ !app ||
15
+ typeof app.singleton !== "function" ||
16
+ typeof app.service !== "function" ||
17
+ typeof app.actions !== "function"
18
+ ) {
19
+ throw new Error("GoogleRewardedCoreProvider requires application singleton()/service()/actions().");
20
+ }
21
+
22
+ app.service(
23
+ "google-rewarded.core.service",
24
+ (scope) => createService({
25
+ googleRewardedRulesRepository: scope.make("repository.google_rewarded_rules"),
26
+ googleRewardedProviderConfigsRepository: scope.make("repository.google_rewarded_provider_configs"),
27
+ googleRewardedWatchSessionsRepository: scope.make("repository.google_rewarded_watch_sessions"),
28
+ googleRewardedUnlockReceiptsRepository: scope.make("repository.google_rewarded_unlock_receipts")
29
+ })
30
+ );
31
+
32
+ app.actions(
33
+ withActionDefaults(googleRewardedActions, {
34
+ domain: "google-rewarded",
35
+ dependencies: {
36
+ googleRewardedService: "google-rewarded.core.service"
37
+ }
38
+ })
39
+ );
40
+ }
41
+
42
+ boot(app) {
43
+ registerRoutes(app, {
44
+ routeOwnershipFilter: "workspace_user",
45
+ routeSurface: "app",
46
+ routeRelativePath: "google-rewarded"
47
+ });
48
+ }
49
+ }
50
+
51
+ export { GoogleRewardedCoreProvider };
@@ -0,0 +1,102 @@
1
+ import {
2
+ currentQueryInputValidator,
3
+ startCommandInputValidator,
4
+ grantCommandInputValidator,
5
+ closeCommandInputValidator,
6
+ currentStateOutputValidator,
7
+ startGateOutputValidator,
8
+ grantRewardOutputValidator,
9
+ closeSessionOutputValidator
10
+ } from "./inputSchemas.js";
11
+
12
+ const ACTION_CURRENT = "google-rewarded.current.read";
13
+ const ACTION_START = "google-rewarded.start";
14
+ const ACTION_GRANT = "google-rewarded.grant";
15
+ const ACTION_CLOSE = "google-rewarded.close";
16
+
17
+ const googleRewardedActions = Object.freeze([
18
+ {
19
+ id: ACTION_CURRENT,
20
+ version: 1,
21
+ kind: "query",
22
+ channels: ["api", "automation", "internal"],
23
+ surfacesFrom: "enabled",
24
+ input: currentQueryInputValidator,
25
+ output: currentStateOutputValidator,
26
+ idempotency: "none",
27
+ audit: {
28
+ actionName: ACTION_CURRENT
29
+ },
30
+ observability: {},
31
+ async execute(input, context, deps) {
32
+ return deps.googleRewardedService.getCurrentState(input, {
33
+ context
34
+ });
35
+ }
36
+ },
37
+ {
38
+ id: ACTION_START,
39
+ version: 1,
40
+ kind: "command",
41
+ channels: ["api", "automation", "internal"],
42
+ surfacesFrom: "enabled",
43
+ input: startCommandInputValidator,
44
+ output: startGateOutputValidator,
45
+ idempotency: "optional",
46
+ audit: {
47
+ actionName: ACTION_START
48
+ },
49
+ observability: {},
50
+ async execute(input, context, deps) {
51
+ return deps.googleRewardedService.startGate(input, {
52
+ context
53
+ });
54
+ }
55
+ },
56
+ {
57
+ id: ACTION_GRANT,
58
+ version: 1,
59
+ kind: "command",
60
+ channels: ["api", "automation", "internal"],
61
+ surfacesFrom: "enabled",
62
+ input: grantCommandInputValidator,
63
+ output: grantRewardOutputValidator,
64
+ idempotency: "optional",
65
+ audit: {
66
+ actionName: ACTION_GRANT
67
+ },
68
+ observability: {},
69
+ async execute(input, context, deps) {
70
+ return deps.googleRewardedService.grantReward(input, {
71
+ context
72
+ });
73
+ }
74
+ },
75
+ {
76
+ id: ACTION_CLOSE,
77
+ version: 1,
78
+ kind: "command",
79
+ channels: ["api", "automation", "internal"],
80
+ surfacesFrom: "enabled",
81
+ input: closeCommandInputValidator,
82
+ output: closeSessionOutputValidator,
83
+ idempotency: "optional",
84
+ audit: {
85
+ actionName: ACTION_CLOSE
86
+ },
87
+ observability: {},
88
+ async execute(input, context, deps) {
89
+ return deps.googleRewardedService.closeSession(input, {
90
+ context
91
+ });
92
+ }
93
+ }
94
+ ]);
95
+
96
+ export {
97
+ ACTION_CURRENT,
98
+ ACTION_START,
99
+ ACTION_GRANT,
100
+ ACTION_CLOSE,
101
+ googleRewardedActions
102
+ };