Skip to content

Conversation

lukasdotcom
Copy link
Member

@lukasdotcom lukasdotcom commented Aug 13, 2025

Adds quota rules that allow you to set a quota for user/group and combinations of them including pools (where quota is shared among a collection of users/groups)
Resolves: #149
image
image

Todo

  • Fix user settings
  • Write tests

@lukasdotcom lukasdotcom force-pushed the feat/quota-rules branch 2 times, most recently from 1a727e5 to 0c24821 Compare August 14, 2025 16:51
@lukasdotcom lukasdotcom marked this pull request as ready for review August 14, 2025 16:54
@lukasdotcom lukasdotcom force-pushed the feat/quota-rules branch 3 times, most recently from 5d30be7 to 2d185f1 Compare August 14, 2025 18:54
@lukasdotcom lukasdotcom force-pushed the feat/quota-rules branch 3 times, most recently from 13fccfc to 3170f18 Compare August 14, 2025 19:27
@lukasdotcom lukasdotcom mentioned this pull request Aug 20, 2025
1 task
Copy link
Member

@julien-nc julien-nc left a comment

Choose a reason for hiding this comment

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

image Aligment issue there.

I'll do a deeper review soon.

@lukasdotcom lukasdotcom force-pushed the feat/quota-rules branch 2 times, most recently from 3ba8178 to e9df9be Compare August 21, 2025 14:10
@lukasdotcom
Copy link
Member Author

image Aligment issue there.

I'll do a deeper review soon.

Centered them as a fix. Squashed and rebased.

@julien-nc julien-nc self-requested a review August 22, 2025 13:45
Copy link
Member

@julien-nc julien-nc left a comment

Choose a reason for hiding this comment

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

  • The "Select users/group" NcSelect could use a max width
  • The save button could appear only if needed
  • The "Rules can be set for specific groups..." NcNoteCard should be displayed after the h2 IMO
  • image How can one have a usage AND a shared usage if the rule overrides the global settings? Is it because a shared rule and a non-shared rules can both apply to a specific user? No overriding there? It deserves some explanation in the UI and in the code.

@lukasdotcom
Copy link
Member Author

  • The "Select users/group" NcSelect could use a max width

    • The save button could appear only if needed

    • The "Rules can be set for specific groups..." NcNoteCard should be displayed after the h2 IMO

    • image How can one have a usage AND a shared usage if the rule overrides the global settings? Is it because a shared rule and a non-shared rules can both apply to a specific user? No overriding there? It deserves some explanation in the UI and in the code.

The usage and shared usage are not for two different rules. Sorry for the confusion. The usage is how much you have used of the shared quota and the shared usage is how much everyone in that group has used of the shared quota. This probably needs a better name though to make it clearer or at least an explanation. Ex: Alice and bob have a shared quota of 200 tokens. Alice used 100 and bob 50. Alice would see the following table

Quota Type Usage Shared Usage
Text Generation 50% 75%

@julien-nc
Copy link
Member

This probably needs a better name though to make it clearer or at least an explanation.

Not sure there is a better naming. A good explanation in the UI would be better already. It could include a small example like:
"If you see a usage of 10% and a shared usage of 50%, it means you used 10% of the shared quota and the sum of all other users affected by this quota is 40%."

@lukasdotcom
Copy link
Member Author

  • The "Select users/group" NcSelect could use a max width

    • The save button could appear only if needed

    • The "Rules can be set for specific groups..." NcNoteCard should be displayed after the h2 IMO

    • image How can one have a usage AND a shared usage if the rule overrides the global settings? Is it because a shared rule and a non-shared rules can both apply to a specific user? No overriding there? It deserves some explanation in the UI and in the code.

Implemented all of these and also disabled the save button while it is being saved and updated the screenshot that shows the new info card.
image

@lukasdotcom lukasdotcom requested a review from julien-nc August 25, 2025 13:52
Copy link
Member

@julien-nc julien-nc left a comment

Choose a reason for hiding this comment

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

  1. If you add migration steps in a PR, always bump the app version number so the people checking out your branch (or later using the main branch) will trigger those migrations.

  2. Mappers are fine like they are now. Small remark: Instead if implementing add, update and delete methods in the mappers, you can directly use the base methods of mappers:

  • create an entity with
$e = new MyEntityClass();
$e->setColA($valA);
$e->setColB($valB);
$e = $myEntitymapper->insert($e);
  • delete with
$myEntitymapper->delete($myEntity);
  • update with
// once you got the entity
$myEntity->setColB($newValB);
$myEntitymapper->update($myEntity);

Copy link
Contributor

@kyteinsky kyteinsky left a comment

Choose a reason for hiding this comment

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

looks nice!

some UI suggestions:

  1. unrelated to this PR sorry, but can you limit the max width of the settings too? The upper part is from Assistant

  2. upper and lower padding correction here so there is a little space above and a little less below:

  3. A per-user quota for each quota type can be set. If the user has not provided their own API key, this quota will be enforced.

    this should be modified to say that it's only used for users/groups not in any of the below quota rule if I understood it correctly.

  4. image

    a. the same upper and lower padding fix can be done here too.
    b. the two input fields for the value and days/months should be aligned vertically
    c. value validation should be done. "Quota rules" sections does it well but a frontend check might save a request ;)

@lukasdotcom
Copy link
Member Author

I think I got everything now and rebased the branch.

4. ![image](https://private-user-images.githubusercontent.com/20724224/482040901-aecb730e-7e87-4454-be42-393266e1cfc5.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTYzMDA1ODAsIm5iZiI6MTc1NjMwMDI4MCwicGF0aCI6Ii8yMDcyNDIyNC80ODIwNDA5MDEtYWVjYjczMGUtN2U4Ny00NDU0LWJlNDItMzkzMjY2ZTFjZmM1LnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTA4MjclMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwODI3VDEzMTEyMFomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPTBlN2QzZDllZjA0YjI0NDZhMjEyOTAwZjIxNDMyZTVkMTZjMjJhMTIzYjQyYmMwMTFiZjQwNDVlYWJlZWMzNWMmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.Rflq3ywwNtiTH5CBEQQukEs-k-csF8z1HL_ygx1uBPA)
   a. the same upper and lower padding fix can be done here too.
   b. the two input fields for the value and days/months should be aligned vertically
   c. value validation should be done. "Quota rules" sections does it well but a frontend check might save a request ;)

For the quota period if you set the length to something less than 1 the backend already made sure the value is not less than 1 and the day is between 1 and 28 when that is used.

@lukasdotcom lukasdotcom force-pushed the feat/quota-rules branch 2 times, most recently from b8dbddd to 3459b82 Compare August 27, 2025 14:47
Signed-off-by: Lukas Schaefer <[email protected]>
@kyteinsky
Copy link
Contributor

For the quota period if you set the length to something less than 1 the backend already made sure the value is not less than 1 and the day is between 1 and 28 when that is used.

sure the backend does but it should not just silently correct it, it should throw an error stating why. Even the frontend should have this check. I think there might be min and max attributes that can be used here too.

@lukasdotcom
Copy link
Member Author

For the quota period if you set the length to something less than 1 the backend already made sure the value is not less than 1 and the day is between 1 and 28 when that is used.

sure the backend does but it should not just silently correct it, it should throw an error stating why. Even the frontend should have this check. I think there might be min and max attributes that can be used here too.

I have the backend now fail with an invalid value and there are min and max values that also prevent saving on the front end.

Copy link
Contributor

@kyteinsky kyteinsky left a comment

Choose a reason for hiding this comment

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

looks good otherwise!

Comment on lines 84 to 87
const typeIconClass = {
user: 'icon-user',
group: 'icon-group',
const typeIconClass = ['icon-user', 'icon-group']
const ENTITY_TYPES = {
user: 0,
group: 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

cool!

Comment on lines +49 to +52
state: loadState('integration_openai', 'rules', []).map((rule) => {
rule.pool = rule.pool === 1
return rule
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

this may be better suited in the backend

<NcAvatar
v-if="option.entity_type === ENTITY_TYPES.user"
:user="option.entity_id"
:show-user-status="false" />
Copy link
Contributor

Choose a reason for hiding this comment

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

ah just noticed there were api calls for user status for all the users. In NC/vue 9, this option has changed to hide-status
https://nextcloud-vue-components.netlify.app/#/Components/NcAvatar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Per user and group usage quota
3 participants