@dappermountain/payload-plugin-achievements 0.2.13 → 0.2.14

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.
@@ -1,4 +1,9 @@
1
1
  import type { PayloadRequest } from 'payload';
2
+ /**
3
+ * Ensure a tier request exists when unlock rules pass.
4
+ * Prefer open (pending/approved) rows. If only a **rejected** request exists,
5
+ * leave it alone — do not auto-queue a new pending after a denial.
6
+ */
2
7
  export declare function ensureTierRequest(args: {
3
8
  req: PayloadRequest;
4
9
  userId: string;
@@ -9,7 +14,8 @@ export declare function ensureTierRequest(args: {
9
14
  created: boolean;
10
15
  }>;
11
16
  /**
12
- * When unlock rules pass and the tier requires review, ensure a pending/approved request exists.
17
+ * When unlock rules pass and the tier requires review, ensure a request exists.
18
+ * Does not recreate a request after rejection — reopen by updating that row or creating manually.
13
19
  */
14
20
  export declare function syncTierProgression(args: {
15
21
  req: PayloadRequest;
@@ -1 +1 @@
1
- {"version":3,"file":"tierProgression.d.ts","sourceRoot":"","sources":["../../../src/services/achievement/tierProgression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,SAAS,CAAA;AAgBpD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAsC9D;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA0DjC;AAED,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA"}
1
+ {"version":3,"file":"tierProgression.d.ts","sourceRoot":"","sources":["../../../src/services/achievement/tierProgression.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAS,MAAM,SAAS,CAAA;AAqBpD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE;IAC5C,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAqD9D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAC9C,GAAG,EAAE,cAAc,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB,GAAG,OAAO,CAAC;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA0DjC;AAED,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAA"}
@@ -2,26 +2,48 @@ import { collectionOf } from '../../collections/helpers.js';
2
2
  import { CTX_SYSTEM_REQUEST } from './contextFlags.js';
3
3
  import { evaluateRules } from './evaluateRules.js';
4
4
  import { hasApprovedTierRequest } from './tierApproval.js';
5
+ function tierRequestScopeClauses(scopeId) {
6
+ if (scopeId)
7
+ return [{ scope: { equals: scopeId } }];
8
+ return [{ scope: { exists: false } }];
9
+ }
10
+ /**
11
+ * Ensure a tier request exists when unlock rules pass.
12
+ * Prefer open (pending/approved) rows. If only a **rejected** request exists,
13
+ * leave it alone — do not auto-queue a new pending after a denial.
14
+ */
5
15
  export async function ensureTierRequest(args) {
6
- const clauses = [
16
+ const base = [
7
17
  { user: { equals: args.userId } },
8
18
  { tier: { equals: args.tierId } },
9
- { status: { in: ['pending', 'approved'] } },
19
+ ...tierRequestScopeClauses(args.scopeId),
10
20
  ];
11
- if (args.scopeId)
12
- clauses.push({ scope: { equals: args.scopeId } });
13
- else
14
- clauses.push({ scope: { exists: false } });
15
- const existing = await args.req.payload.find({
21
+ const open = await args.req.payload.find({
22
+ collection: collectionOf('tierRequests'),
23
+ depth: 0,
24
+ limit: 1,
25
+ overrideAccess: true,
26
+ req: args.req,
27
+ where: {
28
+ and: [...base, { status: { in: ['pending', 'approved'] } }],
29
+ },
30
+ });
31
+ if (open.docs[0]) {
32
+ return { doc: open.docs[0], created: false };
33
+ }
34
+ const rejected = await args.req.payload.find({
16
35
  collection: collectionOf('tierRequests'),
17
36
  depth: 0,
18
37
  limit: 1,
19
38
  overrideAccess: true,
20
39
  req: args.req,
21
- where: { and: clauses },
40
+ sort: '-updatedAt',
41
+ where: {
42
+ and: [...base, { status: { equals: 'rejected' } }],
43
+ },
22
44
  });
23
- if (existing.docs[0]) {
24
- return { doc: existing.docs[0], created: false };
45
+ if (rejected.docs[0]) {
46
+ return { doc: rejected.docs[0], created: false };
25
47
  }
26
48
  args.req.context[CTX_SYSTEM_REQUEST] = true;
27
49
  try {
@@ -43,7 +65,8 @@ export async function ensureTierRequest(args) {
43
65
  }
44
66
  }
45
67
  /**
46
- * When unlock rules pass and the tier requires review, ensure a pending/approved request exists.
68
+ * When unlock rules pass and the tier requires review, ensure a request exists.
69
+ * Does not recreate a request after rejection — reopen by updating that row or creating manually.
47
70
  */
48
71
  export async function syncTierProgression(args) {
49
72
  const scopeId = args.scopeId;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dappermountain/payload-plugin-achievements",
3
- "version": "0.2.13",
3
+ "version": "0.2.14",
4
4
  "description": "A robust, Admin-configured achievements engine for Payload: composable unlock rules, derived rank progress, request/review grants, metrics, and scoped multi-tenant support.",
5
5
  "license": "MIT",
6
6
  "type": "module",