Skip to content

April Fools: Poop tracker#119

Merged
XeIris merged 2 commits intomasterfrom
ei-will-kill-me
Mar 31, 2026
Merged

April Fools: Poop tracker#119
XeIris merged 2 commits intomasterfrom
ei-will-kill-me

Conversation

@XeIris
Copy link
Copy Markdown
Collaborator

@XeIris XeIris commented Mar 31, 2026

Gut health is important
just saying
this april fools
track it better!

Summary by CodeRabbit

  • New Features
    • Added a new "poop" command group with:
      • Profile creation (timezone setting).
      • Entry logging with options for colour, size, type, and duration; confirms entry number on success.
      • Stats command showing totals, averages, last logged time, and common attributes via embedded responses.
      • Paginated leaderboard (all-time/weekly/monthly) with next/previous controls and user-limited pagination.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7b779fb6-1eb2-4308-8e0c-9d0a39d98599

📥 Commits

Reviewing files that changed from the base of the PR and between 7adc2a4 and b6af819.

📒 Files selected for processing (6)
  • commands/poop_log.js
  • commands/poop_profile_create.js
  • commands/poop_stats.js
  • commands/poopboard.js
  • database/models/PoopModel.js
  • database/queries/poopQueries.js
✅ Files skipped from review due to trivial changes (2)
  • commands/poopboard.js
  • database/queries/poopQueries.js
🚧 Files skipped from review as they are similar to previous changes (4)
  • commands/poop_profile_create.js
  • commands/poop_log.js
  • commands/poop_stats.js
  • database/models/PoopModel.js

📝 Walkthrough

Walkthrough

Adds a new "poop" command group with subcommands (profile-create, log, stats, leaderboard), full persistence via new DB tables and model, SQL query definitions, and a leaderboard command with pagination and interaction handling. All commands hook into the new PoopModel through Database.get poop().

Changes

Cohort / File(s) Summary
Command group & subcommands
commands/commandgroups/poop.js, commands/poop_log.js, commands/poop_profile_create.js, commands/poop_stats.js, commands/poopboard.js
Adds a new poop command group and four subcommands: profile-create, log, stats, and leaderboard (poopboard). Implements slash options, interaction replies/embeds, DB calls to PoopModel, error logging, and leaderboard pagination with button collector.
Database model & integration
database/Database.js, database/models/PoopModel.js, database/models/index.js
Introduces PoopModel with methods for profile upsert, logging entries, fetching stats, and leaderboard queries; exposes it via Database.get poop() and exports it from models index.
Queries
database/queries/poopQueries.js
Adds parameterized SQL: profile upsert/select, insert poop entry, per-user counts/stats (total, last, avg, most common), leaderboard and leaderboard count builders supporting weekly/monthly filters.
Table schemas & registry
database/tables/poopProfileTable.js, database/tables/poopEntryTable.js, database/tables/index.js
Adds PoopProfile (user_id PK, timezone) and PoopEntry (id PK, user_id FK, logged_at, colour, size, type, duration) table definitions and registers them in tables index.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Discord as Discord API
  participant Bot as Bot Command Handler
  participant DB as PoopModel / Database

  User->>Discord: /poop log (colour,size,type,duration)
  Discord->>Bot: interaction create
  Bot->>Discord: interaction.reply (deferred)
  Bot->>DB: logPoop(userId, colour, size, type, duration)
  DB->>DB: ensure profile (create timezone=0 if missing)
  DB->>DB: insert PoopEntry, query new count
  DB-->>Bot: return entryCount
  Bot->>Discord: interaction.editReply("Entry success #<count>")
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

enhancement

Poem

🐰💨
I hopped in with code and a cheeky grin,
Tracking little logs where mischief begins.
Profiles, stats, and a leaderboard cheer —
April trickery recorded year after year! 💩✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'April Fools: Poop tracker' directly and clearly summarizes the main change—adding an April Fools poop tracking feature with multiple commands and database models.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ei-will-kill-me

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (2)
database/queries/poopQueries.js (2)

21-44: GET_USER_STATS query requires the same parameter three times.

The query has three ? placeholders (lines 28, 33, 43), all expecting userId. This works but requires callers to pass the same value three times. This is handled correctly in PoopModel.getUserStats, but consider documenting this requirement or restructuring with a CTE.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@database/queries/poopQueries.js` around lines 21 - 44, The GET_USER_STATS SQL
uses three positional placeholders for the same userId; change it to a single
named parameter (e.g., :userId) in the query (replace all three ? in
GET_USER_STATS with :userId) and update PoopModel.getUserStats to bind that
named parameter once when executing the query so callers no longer need to pass
the same value three times; alternatively, if you prefer a SQL-only fix, wrap
the repeated subqueries in a CTE that filters by user_id once, but prefer the
named-parameter approach for minimal code changes.

62-73: Same pattern issues in GET_LEADERBOARD_COUNT.

While less critical here (no limit/offset), consider consistency with the main leaderboard query for maintainability.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@database/queries/poopQueries.js` around lines 62 - 73, GET_LEADERBOARD_COUNT
builds its own periodFilter differently than the main GET_LEADERBOARD query,
making behavior and future maintenance inconsistent; update
GET_LEADERBOARD_COUNT to mirror the period handling used by GET_LEADERBOARD
(reuse the same period filter logic or a shared helper) so both functions
produce identical date criteria for 'weekly' and 'monthly' (i.e., ensure the
same strftime expression and field used for logged_at), and refactor to
centralize the periodFilter construction so GET_LEADERBOARD_COUNT calls that
helper or uses the identical expression.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@commands/poop_log.js`:
- Around line 62-77: The error handler in the run method is calling
interaction.editReply({ ..., ephemeral: true }) but ephemeral cannot be changed
on editReply; either remove the ineffective ephemeral flag from the editReply
call in the run method (and just call interaction.editReply('Failed to
record...')), or make the interaction ephemeral from the start by updating where
the command defers/replies (e.g., ensure Command class or the code that calls
interaction.deferReply() or interaction.reply() uses { ephemeral: true }) so
subsequent editReply stays ephemeral; update the run method and/or the Command
base to be consistent (refer to run, interaction.editReply,
interaction.deferReply / interaction.reply, and the Command class).

In `@commands/poop_profile_create.js`:
- Around line 39-42: The catch block in poop_profile_create.js is relying on
interaction.editReply({ ephemeral: true }) which has no effect; ensure the
initial interaction deferral/reply (in the command entry handler or base Command
class where deferReply/reply is called) includes { ephemeral: true }, or change
error reporting here to use interaction.followUp({ content: 'Failed to save your
timezone. Please try again.', ephemeral: true }) so the error is private; also
modify PoopModel.createOrUpdateProfile to propagate failures (throw the DB error
or return a clear success boolean) and update the caller in
poop_profile_create.js to check that result and only send the success embed when
the DB write actually succeeded, logging and sending the ephemeral error when it
did not (use logError to record the thrown error).

In `@commands/poop_stats.js`:
- Around line 69-72: The catch block in commands/poop_stats.js incorrectly sets
ephemeral on interaction.editReply (which has no effect); remove the ephemeral
option from interaction.editReply and instead ensure the initial response is
created as ephemeral (e.g., call interaction.deferReply({ ephemeral: true }) or
use interaction.reply({ ephemeral: true }) where the command starts), so that
the error follow-up via interaction.editReply shows as ephemeral to the user.

In `@commands/poopboard.js`:
- Around line 6-16: The constructor in class PoopBoard passes the wrong
attribute name ('poopCount') to LeaderboardMixin which doesn't match the
DB/GET_LEADERBOARD field ('poop_count'); update the attribute argument in
PoopBoard's constructor from 'poopCount' to 'poop_count' so generateLeaderboard
reads the correct property returned by GET_LEADERBOARD (see PoopBoard,
LeaderboardMixin, constructor, generateLeaderboard, and poopQueries.js).
- Around line 62-90: The collector currently allows any user to control
pagination; restrict it to the command invoker by checking interaction user
identity before handling pagination. Update the component collector usage around
message.createMessageComponentCollector and the collector.on('collect', ...)
handler in the pagination logic: either supply a filter that only accepts
interactions where i.user.id === message.author.id, or at the start of the
'collect' handler verify i.user.id === message.author.id and if not, respond
with an ephemeral rejection (e.g., i.reply({ content: 'You cannot control this
pagination', ephemeral: true })) and return; only proceed to fetch
newAttrs/generateLeaderboard/i.update for the allowed user. Ensure you reference
the existing collector, i (interaction), message, and currentPage/maxPage logic
when making this change.

In `@database/models/PoopModel.js`:
- Around line 40-43: The code reads countRow?.poopCount but the SQL alias is
poop_count; update whichever is easier: either change the GET_USER_POOP_COUNT
query to alias COUNT(*) as poopCount, or change the model code to read
countRow?.poop_count (and keep the default behavior). Locate the call to
this.db.executeSelectQuery(GET_USER_POOP_COUNT, ...) and the variables countRow
and count to apply the fix so the returned column name matches the property
accessed before logging and returning the value.
- Around line 9-14: The createOrUpdateProfile function currently ignores the
result of this.db.executeQuery and always logs success; change
createOrUpdateProfile to capture the result of this.db.executeQuery(query,
[userId, timezone]), check result.changes (or equivalent) and throw an Error or
return a rejected Promise when changes === 0 (or lastID is null) so callers can
detect failure; ensure the error includes context (userId/timezone and query)
and remove the unconditional success log or only log on verified success; update
callers like poop_profile_create.js to handle the thrown error or rejected
promise if they don't already.

In `@database/queries/poopQueries.js`:
- Around line 46-60: The GET_LEADERBOARD query currently interpolates limit and
offset directly and returns poop_count (snake_case), creating an SQL injection
risk and a naming mismatch with PoopBoard/LeaderboardMixin; change
GET_LEADERBOARD to use parameter placeholders for LIMIT and OFFSET (e.g., ? or
$n according to your DB driver) and alias the count column to match the model
attribute (poopCount) or update PoopBoard to expect poop_count; then update
PoopModel.getLeaderboard to pass limit and offset as query parameters instead of
interpolating them, ensuring LeaderboardMixin.generateLeaderboard reads
attrs[i][this.attribute] correctly.

---

Nitpick comments:
In `@database/queries/poopQueries.js`:
- Around line 21-44: The GET_USER_STATS SQL uses three positional placeholders
for the same userId; change it to a single named parameter (e.g., :userId) in
the query (replace all three ? in GET_USER_STATS with :userId) and update
PoopModel.getUserStats to bind that named parameter once when executing the
query so callers no longer need to pass the same value three times;
alternatively, if you prefer a SQL-only fix, wrap the repeated subqueries in a
CTE that filters by user_id once, but prefer the named-parameter approach for
minimal code changes.
- Around line 62-73: GET_LEADERBOARD_COUNT builds its own periodFilter
differently than the main GET_LEADERBOARD query, making behavior and future
maintenance inconsistent; update GET_LEADERBOARD_COUNT to mirror the period
handling used by GET_LEADERBOARD (reuse the same period filter logic or a shared
helper) so both functions produce identical date criteria for 'weekly' and
'monthly' (i.e., ensure the same strftime expression and field used for
logged_at), and refactor to centralize the periodFilter construction so
GET_LEADERBOARD_COUNT calls that helper or uses the identical expression.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 89b83373-45a0-4156-9cc5-bb6465f6bdcf

📥 Commits

Reviewing files that changed from the base of the PR and between a975a2c and 7adc2a4.

📒 Files selected for processing (12)
  • commands/commandgroups/poop.js
  • commands/poop_log.js
  • commands/poop_profile_create.js
  • commands/poop_stats.js
  • commands/poopboard.js
  • database/Database.js
  • database/models/PoopModel.js
  • database/models/index.js
  • database/queries/poopQueries.js
  • database/tables/index.js
  • database/tables/poopEntryTable.js
  • database/tables/poopProfileTable.js

Comment thread commands/poop_log.js
Comment on lines +39 to +42
} catch (error) {
logError('Failed to create poop profile:', error);
await interaction.editReply({ content: 'Failed to save your timezone. Please try again.', ephemeral: true });
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

The ephemeral: true flag has no effect on editReply.

In discord.js v14, the ephemeral property must be set on the initial reply() or deferReply() call. Setting it on editReply() is silently ignored, so the error message will be visible to everyone in the channel.

Additionally, per the context snippet from PoopModel.js, createOrUpdateProfile does not propagate database errors—it only logs success. If the DB write fails, no exception is thrown, so this catch block won't execute and the user will see a success embed despite the failure.

Proposed fix

For the ephemeral issue, ensure the command's initial deferral (likely in the base Command class) uses ephemeral: true when needed, or handle the error with a followUp:

    } catch (error) {
      logError('Failed to create poop profile:', error);
-     await interaction.editReply({ content: 'Failed to save your timezone. Please try again.', ephemeral: true });
+     await interaction.editReply({ content: 'Failed to save your timezone. Please try again.' });
    }

For the silent DB error issue, createOrUpdateProfile in PoopModel.js should propagate errors or return a success indicator.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
logError('Failed to create poop profile:', error);
await interaction.editReply({ content: 'Failed to save your timezone. Please try again.', ephemeral: true });
}
} catch (error) {
logError('Failed to create poop profile:', error);
await interaction.editReply({ content: 'Failed to save your timezone. Please try again.' });
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/poop_profile_create.js` around lines 39 - 42, The catch block in
poop_profile_create.js is relying on interaction.editReply({ ephemeral: true })
which has no effect; ensure the initial interaction deferral/reply (in the
command entry handler or base Command class where deferReply/reply is called)
includes { ephemeral: true }, or change error reporting here to use
interaction.followUp({ content: 'Failed to save your timezone. Please try
again.', ephemeral: true }) so the error is private; also modify
PoopModel.createOrUpdateProfile to propagate failures (throw the DB error or
return a clear success boolean) and update the caller in poop_profile_create.js
to check that result and only send the success embed when the DB write actually
succeeded, logging and sending the ephemeral error when it did not (use logError
to record the thrown error).

Comment thread commands/poop_stats.js
Comment on lines +69 to +72
} catch (error) {
logError('Failed to fetch poop stats:', error);
await interaction.editReply({ content: 'Failed to retrieve poop stats. Please try again.', ephemeral: true });
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Same ephemeral: true issue as in poop_log.js.

The ephemeral flag on editReply has no effect—ephemeral status is fixed at deferReply/reply time.

Proposed fix
     } catch (error) {
       logError('Failed to fetch poop stats:', error);
-      await interaction.editReply({ content: 'Failed to retrieve poop stats. Please try again.', ephemeral: true });
+      await interaction.editReply('Failed to retrieve poop stats. Please try again.');
     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} catch (error) {
logError('Failed to fetch poop stats:', error);
await interaction.editReply({ content: 'Failed to retrieve poop stats. Please try again.', ephemeral: true });
}
} catch (error) {
logError('Failed to fetch poop stats:', error);
await interaction.editReply('Failed to retrieve poop stats. Please try again.');
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/poop_stats.js` around lines 69 - 72, The catch block in
commands/poop_stats.js incorrectly sets ephemeral on interaction.editReply
(which has no effect); remove the ephemeral option from interaction.editReply
and instead ensure the initial response is created as ephemeral (e.g., call
interaction.deferReply({ ephemeral: true }) or use interaction.reply({
ephemeral: true }) where the command starts), so that the error follow-up via
interaction.editReply shows as ephemeral to the user.

Comment thread commands/poopboard.js
Comment on lines +6 to +16
class PoopBoard extends LeaderboardMixin(Command) {
constructor(client) {
super(
client,
'poopboard',
'See who has pooped the most 💩',
'Poop Leaderboard 💩',
'poopCount',
'Poops',
'No one has pooped yet... or have they? 🤔',
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Attribute name mismatch will cause display issues.

The constructor passes 'poopCount' (line 13) as the attribute, but GET_LEADERBOARD returns poop_count. This mismatch causes generateLeaderboard to display "undefined" for each user's count. See the related comment on poopQueries.js for the fix.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@commands/poopboard.js` around lines 6 - 16, The constructor in class
PoopBoard passes the wrong attribute name ('poopCount') to LeaderboardMixin
which doesn't match the DB/GET_LEADERBOARD field ('poop_count'); update the
attribute argument in PoopBoard's constructor from 'poopCount' to 'poop_count'
so generateLeaderboard reads the correct property returned by GET_LEADERBOARD
(see PoopBoard, LeaderboardMixin, constructor, generateLeaderboard, and
poopQueries.js).

Comment thread commands/poopboard.js
Comment thread database/models/PoopModel.js
Comment on lines +40 to +43
const countRow = await this.db.executeSelectQuery(poopQueries.GET_USER_POOP_COUNT, [userId]);
const count = countRow?.poopCount ?? 1;
log(`User ${userId} logged poop #${count}`);
return count;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Column name mismatch: SQL returns poop_count, code expects poopCount.

GET_USER_POOP_COUNT returns COUNT(*) as poop_count, but line 41 accesses countRow?.poopCount. This will always be undefined, causing the count to default to 1 regardless of actual poop count.

Proposed fix

Either update the query in poopQueries.js:

  GET_USER_POOP_COUNT: `
-   SELECT COUNT(*) as poop_count FROM PoopEntry WHERE user_id = ?
+   SELECT COUNT(*) as poopCount FROM PoopEntry WHERE user_id = ?
  `,

Or update the model:

    const countRow = await this.db.executeSelectQuery(poopQueries.GET_USER_POOP_COUNT, [userId]);
-   const count = countRow?.poopCount ?? 1;
+   const count = countRow?.poop_count ?? 1;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const countRow = await this.db.executeSelectQuery(poopQueries.GET_USER_POOP_COUNT, [userId]);
const count = countRow?.poopCount ?? 1;
log(`User ${userId} logged poop #${count}`);
return count;
const countRow = await this.db.executeSelectQuery(poopQueries.GET_USER_POOP_COUNT, [userId]);
const count = countRow?.poop_count ?? 1;
log(`User ${userId} logged poop #${count}`);
return count;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@database/models/PoopModel.js` around lines 40 - 43, The code reads
countRow?.poopCount but the SQL alias is poop_count; update whichever is easier:
either change the GET_USER_POOP_COUNT query to alias COUNT(*) as poopCount, or
change the model code to read countRow?.poop_count (and keep the default
behavior). Locate the call to this.db.executeSelectQuery(GET_USER_POOP_COUNT,
...) and the variables countRow and count to apply the fix so the returned
column name matches the property accessed before logging and returning the
value.

Comment thread database/queries/poopQueries.js Outdated
Comment on lines +46 to +60
GET_LEADERBOARD: (period, limit, offset) => {
const periodFilter = period === 'weekly'
? `AND logged_at >= strftime('%s', 'now', '-7 days')`
: period === 'monthly'
? `AND logged_at >= strftime('%s', 'now', '-30 days')`
: '';
return `
SELECT user_id as id, COUNT(*) as poop_count
FROM PoopEntry
WHERE 1=1 ${periodFilter}
GROUP BY user_id
ORDER BY poop_count DESC
LIMIT ${limit} OFFSET ${offset}
`;
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

SQL injection vulnerability via limit and offset interpolation.

The limit and offset values are directly interpolated into the SQL string. While these likely come from internal code, this pattern is risky if values ever originate from user input. Use parameterized queries instead.

Also, the query returns poop_count (snake_case), but the PoopBoard constructor sets this.attribute = 'poopCount' (camelCase). The LeaderboardMixin.generateLeaderboard method accesses attrs[i][this.attribute], which will be undefined since the row has poop_count, not poopCount. This will display "undefined" for every user's count.

Proposed fix
  GET_LEADERBOARD: (period, limit, offset) => {
    const periodFilter = period === 'weekly'
      ? `AND logged_at >= strftime('%s', 'now', '-7 days')`
      : period === 'monthly'
        ? `AND logged_at >= strftime('%s', 'now', '-30 days')`
        : '';
    return `
-     SELECT user_id as id, COUNT(*) as poop_count
+     SELECT user_id as id, COUNT(*) as poopCount
      FROM PoopEntry
      WHERE 1=1 ${periodFilter}
      GROUP BY user_id
-     ORDER BY poop_count DESC
-     LIMIT ${limit} OFFSET ${offset}
+     ORDER BY poopCount DESC
+     LIMIT ? OFFSET ?
    `;
  },

Note: Switching to parameterized LIMIT/OFFSET requires updating PoopModel.getLeaderboard to pass these as query parameters.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@database/queries/poopQueries.js` around lines 46 - 60, The GET_LEADERBOARD
query currently interpolates limit and offset directly and returns poop_count
(snake_case), creating an SQL injection risk and a naming mismatch with
PoopBoard/LeaderboardMixin; change GET_LEADERBOARD to use parameter placeholders
for LIMIT and OFFSET (e.g., ? or $n according to your DB driver) and alias the
count column to match the model attribute (poopCount) or update PoopBoard to
expect poop_count; then update PoopModel.getLeaderboard to pass limit and offset
as query parameters instead of interpolating them, ensuring
LeaderboardMixin.generateLeaderboard reads attrs[i][this.attribute] correctly.

@XeIris XeIris self-assigned this Mar 31, 2026
@XeIris XeIris merged commit 51f4c32 into master Mar 31, 2026
1 check passed
@coderabbitai coderabbitai Bot mentioned this pull request Apr 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant