Problem
The add-or-update operation involves cloning repositories, scanning for translatable files, creating Weblate components, and importing translations — work that can take minutes. This must run asynchronously in a Celery worker, not in the HTTP request path. A Celery task definition is needed that receives the validated parameters from the view, reconstructs the user context in the worker, and delegates to the service layer.
Acceptance Criteria
Implementation Notes
Use bind=True on the task so self is available for retry logic. The user context reconstruction should use django.contrib.auth.get_user_model().objects.get(pk=user_id) with a DoesNotExist guard. The per-language iteration pattern: loop over languages, calling services.process_language(user, project_slug, repo_url, lang) for each. Consider using self.update_state() to report progress per language.
References
- Related files:
src/boost_weblate/tasks.py, src/boost_weblate/services.py
- Depends on:
views.py (caller), services.py (callee)
Problem
The add-or-update operation involves cloning repositories, scanning for translatable files, creating Weblate components, and importing translations — work that can take minutes. This must run asynchronously in a Celery worker, not in the HTTP request path. A Celery task definition is needed that receives the validated parameters from the view, reconstructs the user context in the worker, and delegates to the service layer.
Acceptance Criteria
src/boost_weblate/tasks.pydefines anadd_or_updateCelery task decorated with@shared_task(or@app.taskwith the correct app reference)user_id,project_slug,repo_url, andlanguagesas parametersUserobject fromuser_idfor permission-scoped operationsservices.pyfor the actual work, iterating per-language as neededmax_retries=3,default_retry_delay=60) for transient failures202response can be used to query task status via Celery's result backendImplementation Notes
Use
bind=Trueon the task soselfis available for retry logic. The user context reconstruction should usedjango.contrib.auth.get_user_model().objects.get(pk=user_id)with aDoesNotExistguard. The per-language iteration pattern: loop overlanguages, callingservices.process_language(user, project_slug, repo_url, lang)for each. Consider usingself.update_state()to report progress per language.References
src/boost_weblate/tasks.py,src/boost_weblate/services.pyviews.py(caller),services.py(callee)