add template folder CRUD

* create template folder
* rename template folder
* get list of template folders for service (not nested/presented in any
  particular way)
* delete template folder

Also removed `lazy=dynamic` from the `template_folder.templates`
relationship. lazy=dynamic returns a query object (which you can then
filter further). We just want to return the entire fetched list, at
least for now.
This commit is contained in:
Leo Hemsted
2018-10-30 16:26:25 +00:00
parent f0c61c8f29
commit fbe34041d6
9 changed files with 338 additions and 4 deletions

View File

@@ -114,6 +114,7 @@ def register_blueprint(application):
from app.organisation.invite_rest import organisation_invite_blueprint
from app.complaint.complaint_rest import complaint_blueprint
from app.platform_stats.rest import platform_stats_blueprint
from app.template_folder.rest import template_folder_blueprint
service_blueprint.before_request(requires_admin_auth)
application.register_blueprint(service_blueprint, url_prefix='/service')
@@ -196,6 +197,9 @@ def register_blueprint(application):
platform_stats_blueprint.before_request(requires_admin_auth)
application.register_blueprint(platform_stats_blueprint, url_prefix='/platform-stats')
template_folder_blueprint.before_request(requires_admin_auth)
application.register_blueprint(template_folder_blueprint)
def register_v2_blueprints(application):
from app.v2.inbound_sms.get_inbound_sms import v2_inbound_sms_blueprint as get_inbound_sms

View File

@@ -0,0 +1,22 @@
from app import db
from app.dao.dao_utils import transactional
from app.models import TemplateFolder
def dao_get_template_folder_by_id(template_folder_id):
return TemplateFolder.query.filter(TemplateFolder.id == template_folder_id).one()
@transactional
def dao_create_template_folder(template_folder):
db.session.add(template_folder)
@transactional
def dao_update_template_folder(template_folder):
db.session.add(template_folder)
@transactional
def dao_delete_template_folder(template_folder):
db.session.delete(template_folder)

View File

@@ -714,8 +714,16 @@ class TemplateFolder(db.Model):
name = db.Column(db.String, nullable=False)
parent_id = db.Column(UUID(as_uuid=True), db.ForeignKey('template_folder.id'), nullable=True)
service = db.relationship('Service')
parent = db.relationship('TemplateFolder', remote_side=[id], backref='children')
service = db.relationship('Service', backref='all_template_folders')
parent = db.relationship('TemplateFolder', remote_side=[id], backref='subfolders')
def serialize(self):
return {
'id': self.id,
'name': self.name,
'parent_id': self.parent_id,
'service_id': self.service_id
}
template_folder_map = db.Table(
@@ -864,7 +872,7 @@ class Template(TemplateBase):
uselist=False,
# eagerly load the folder whenever the template object is fetched
lazy='joined',
backref=db.backref('templates', lazy='dynamic')
backref=db.backref('templates')
)
def get_link(self):

View File

@@ -11,6 +11,14 @@ uuid = {
"link": "link to our error documentation not yet implemented"
}
nullable_uuid = {
"type": ["string", "null"],
"format": "validate_uuid",
"validationMessage": "is not a valid UUID",
"code": "1001", # yet to be implemented
"link": "link to our error documentation not yet implemented"
}
personalisation = {
"type": "object",

View File

View File

@@ -0,0 +1,84 @@
from flask import Blueprint, jsonify, request
from sqlalchemy.exc import IntegrityError
from app.dao.template_folder_dao import (
dao_create_template_folder,
dao_get_template_folder_by_id,
dao_update_template_folder,
dao_delete_template_folder
)
from app.dao.services_dao import dao_fetch_service_by_id
from app.errors import register_errors
from app.models import TemplateFolder
from app.template_folder.template_folder_schema import (
post_create_template_folder_schema,
post_rename_template_folder_schema
)
from app.schema_validation import validate
template_folder_blueprint = Blueprint(
'template_folder',
__name__,
url_prefix='/service/<uuid:service_id>/template-folder'
)
register_errors(template_folder_blueprint)
@template_folder_blueprint.errorhandler(IntegrityError)
def handle_integrity_error(exc):
if 'template_folder_parent_id_fkey' in str(exc):
return jsonify(result='error', message='parent_id not found'), 400
raise
@template_folder_blueprint.route('', methods=['GET'])
def get_template_folders_for_service(service_id):
service = dao_fetch_service_by_id(service_id)
template_folders = [o.serialize() for o in service.all_template_folders]
return jsonify(template_folders=template_folders)
@template_folder_blueprint.route('', methods=['POST'])
def create_template_folder(service_id):
data = request.get_json()
validate(data, post_create_template_folder_schema)
template_folder = TemplateFolder(
service_id=service_id,
name=data['name'].strip(),
parent_id=data['parent_id']
)
dao_create_template_folder(template_folder)
return jsonify(data=template_folder.serialize()), 201
@template_folder_blueprint.route('/<uuid:template_folder_id>/rename', methods=['POST'])
def rename_template_folder(service_id, template_folder_id):
data = request.get_json()
validate(data, post_rename_template_folder_schema)
template_folder = dao_get_template_folder_by_id(template_folder_id)
template_folder.name = data['name']
dao_update_template_folder(template_folder)
return jsonify(data=template_folder.serialize()), 200
@template_folder_blueprint.route('/<uuid:template_folder_id>', methods=['DELETE'])
def delete_template_folder(service_id, template_folder_id):
template_folder = dao_get_template_folder_by_id(template_folder_id)
# don't allow deleting if there's anything in the folder (even if it's just more empty subfolders)
if template_folder.subfolders or template_folder.templates:
return jsonify(result='error', message='Folder is not empty'), 400
dao_delete_template_folder(template_folder)
return '', 204

View File

@@ -0,0 +1,22 @@
from app.schema_validation.definitions import nullable_uuid
post_create_template_folder_schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "POST schema for getting template_folder",
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
"parent_id": nullable_uuid
},
"required": ["name", "parent_id"]
}
post_rename_template_folder_schema = {
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "POST schema for renaming template_folder",
"type": "object",
"properties": {
"name": {"type": "string", "minLength": 1},
},
"required": ["name"]
}